Инженерный английский Задачи и баг-репорты: как описать, чтобы поняли с первого раза
0%

Задачи и баг-репорты: как описать, чтобы поняли с первого раза

Задачи и баг-репорты: как описать, чтобы поняли с первого раза

Есть один измеримый критерий хорошего тикета, и он не про грамматику: исполнитель может начать работу, не задав ни одного вопроса. Всё остальное — стиль, артикли, выбор между behaviour и behavior — второстепенно по отношению к этому. Тикет, после которого прилетело «Could you clarify what exactly you did?», не выполнил свою функцию, даже если написан безупречным английским. Тикет с тремя грамматическими ошибками, по которому человек за две минуты воспроизвёл баг, свою функцию выполнил.

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

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

Эта глава — про механику текста в трекере. Она не про процесс работы с багами (это тестирование и поддержка), не про формулировку требований (это системный анализ) и не про приоритизацию бэклога (это Scrum). Здесь — что именно написать буквами, как это прочитает получатель и как переписать.

Кто читает ваш тикет и в каком режиме

Тикет читают минимум три разных человека в трёх разных режимах, и они предъявляют к тексту несовместимые требования. Пока эта модель не в голове, непонятно, почему «и так же всё написано» не работает.

Триажер просматривает список из сорока новых issue. На каждый у него пять-десять секунд, и он видит только заголовок и ярлыки — тело не открывает. Его задача: решить, это баг или вопрос, кому это принадлежит, срочно ли. Всё, что не поместилось в первые ~60 символов заголовка, для него не существует.

Исполнитель открыл тикет и пытается воспроизвести. Ему нужны шаги, окружение, версия, точный текст ошибки и разница между ожидаемым и фактическим. Его блокирует любая дырка: неизвестная версия, «в некоторых случаях», скриншот вместо текста ошибки.

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

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

Сколько стоит один недостающий факт

Арифметика простая и неприятная. Команда распределена по часовым поясам с разницей 6–9 часов. Вы отправили неполный репорт в 18:00 по своему времени. Исполнитель увидел его в свой рабочий день, задал вопрос, вы уже спите. Вы ответили следующим утром, он спит. Один недостающий факт — примерно сутки календаря; два вопроса подряд, заданные последовательно, — двое суток.

Никакого исследования тут нет — есть арифметика асинхронности, проверяемая на собственном трекере за пять минут. Вывод: полнота репорта важнее языковой чистоты ровно настолько, насколько сутки дороже секунд. Отсюда правило: сомневаетесь, включать ли факт, — включайте; лишняя строчка стоит читателю секунду, недостающая — сутки. Про асинхронный режим целиком — глава Асинхронная переписка.

Заголовок: одна строка, которую прочитают все

Анатомия заголовка issue и граница обрезки в списке трекера

У заголовка своя грамматика, отличная от грамматики обычного предложения. Она называется телеграфным стилем и устроена так: подлежащее-система, глагол наблюдаемого поведения, условие. Артикли в начале допустимо опускать (Export fails…, а не The export fails…), точка в конце не ставится, восклицательные знаки не ставятся никогда.

Глагол решает больше, чем всё остальное

Самая частая формулировка русскоязычного инженера — doesn't work — не содержит информации. Сравните, что сообщают глаголы, каждый из которых означает свой класс проблемы:

Глагол Что он сообщает читателю Куда он направит первый взгляд
fails операция завершилась неуспехом, есть явный отказ код возврата, обработчик ошибки
returns 500 ответ пришёл, но неуспешный логи сервера, стектрейс
returns stale data ответ успешный, но содержимое неверное кэш, репликация, инвалидация
times out ответа не было в отведённое время таймауты, блокировки, медленный запрос
hangs процесс не завершается и не отдаёт ошибку дедлок, бесконечный цикл, ожидание ресурса
crashes процесс аварийно завершился дамп, сигнал, паника
throws NullPointerException конкретное исключение точное место в коде
leaks memory потребление растёт без возврата профилирование

Это не список полезных фраз для заучивания — это карта диагнозов. Выбирая глагол, вы уже делаете половину триажа: times out и crashes попадут к разным людям. Именно поэтому doesn't work бесполезно: оно не сужает поиск ни на шаг.

Время глагола сообщает воспроизводимость

Здесь есть тонкость, которую почти никто не проговаривает, а носитель считывает автоматически:

  • Present simpleExport times out for ranges longer than 31 days — читается как «это свойство системы, воспроизводится». Это норма для баг-репорта.
  • Past simpleExport timed out during the release on 14 March — читается как «был единичный случай в прошлом». Это норма для инцидента и постмортема, но в обычном баг-репорте создаёт впечатление, что проблема уже неактуальна.
  • Present continuousExport is timing out — читается как «прямо сейчас, возможно временно». Уместно в чате во время инцидента, неуместно в заголовке issue: через неделю непонятно, о чём речь.

Ошибка «написал past simple про воспроизводимый баг» приводит к предсказуемому итогу: тикет закрывают как not reproducible, потому что читатель понял, что речь про разовое событие. Про язык инцидентов и то, чем он отличается, — SRE: реагирование на инциденты.

Разбор реальных заголовков

Ниже — формулировки, которые действительно приходят в трекеры, и то, как они читаются на той стороне.

1. Bug in export → «здесь что-то есть, разбирайтесь сами». Слово bug в заголовке избыточно: тикет уже лежит в трекере багов и имеет ярлык. Родственный случай — Export doesn't work correctly: correctly сообщает, что вы знаете, как правильно, но не говорите, а проверить «правильность» читатель не может. Переписываем: CSV export writes the header twice when the report has more than 1000 rows.

2. URGENT!!! Production is down!!! → капслок и восклицательные знаки не ускоряют реакцию, а расходуют доверие: если следующий тикет действительно про падение, ему уже не поверят. Кроме того, для инцидентов в норме есть отдельный канал, а не трекер. Переписываем: Checkout API returns 503 for all requests since 14:20 UTC. Факт со временем работает быстрее любых знаков препинания.

3. Can't login → чей логин, какой метод, какая ошибка? Заголовок из двух слов вынуждает открыть тело — а триажер тело не открывает. Переписываем: SSO login fails with "invalid_grant" for users whose email was changed in the last 24 hours. Длинно, но это ровно та строка, которую через полгода найдут поиском.

4. Fix the retry logic → это не описание проблемы, а готовое решение. Заголовок-решение опасен тем, что закрывает обсуждение: если ваш диагноз неверен, никто уже не проверит симптом. Переписываем: Payment retries fire three times within one second, which triggers rate limiting. Решение — в теле, отдельным абзацем.

Полезная проверка на английский: если заголовок можно поставить в предложение We reproduced that ______, и получится осмысленная фраза — заголовок описывает наблюдаемое поведение. We reproduced that export times out for large ranges — работает. We reproduced that fix the retry logic — очевидно нет.

Тело: четыре блока и четыре вопроса

Канонический скелет баг-репорта существует не одно десятилетие и почти не менялся: он есть в руководстве Mozilla по написанию багов, в правилах Chromium и в классическом эссе Саймона Тэтхэма «How to Report Bugs Effectively», написанном ещё в 1999 году и не устаревшем ни на строчку. Четыре обязательных блока отвечают на четыре вопроса читателя — «как повторить», «чего вы ждали», «что получилось», «где это было»; пятый, Notes, существует для гипотез.

## Summary
Report export times out for date ranges longer than 31 days.

## Steps to reproduce
1. Sign in as a user with the `analyst` role.
2. Open **Reports → Sales**.
3. Set the date range to 01 Jan – 15 Feb.
4. Click **Export to CSV**.

## Expected
The browser downloads a CSV file within 30 seconds.

## Actual
The request to `POST /v1/reports/export` returns 504 after 60 seconds.
Response body: `{"error":"gateway_timeout","request_id":"8f21ac"}`
Reproduced 5 out of 5 times.

## Environment
App 4.2.1 (build 3921), Chrome 126, macOS 14.5, tenant `acme-eu`, region `eu-central-1`.

## Notes
Ranges of 30 days or less finish in about 4 seconds, so the boundary looks like the
31-day mark. I have not checked whether the timeout is in the gateway or in the worker.

Разберём язык каждого блока — здесь есть несколько неочевидных вещей.

Steps to reproduce — императив, по одному действию на строку. Правильно: Open the settings page. Неправильно: We should open the settings page (это не инструкция, а предложение обсудить), I opened the settings page and then I clicked… (рассказ от первого лица, читателю приходится вылавливать действия из повествования) и You need to open settings (лишняя модальность). Императив в английском не звучит грубо в инструкциях — это стандартный жанровый регистр, тот же, что в документации; Google developer documentation style guide прямо предписывает императив для процедур. Одно действие на строку — чтобы читатель мог сказать «у меня получилось до шага 3».

Expected и Actual — оба в present simple, оба про наблюдаемое. Частая ошибка: The system must return 200. Глагол must в техническом английском занят: он означает нормативное требование в смысле RFC 2119 — об этом подробно в главе Стандарты и RFC. В баг-репорте вы не выдвигаете требование, вы описываете расхождение, поэтому: Expected: the endpoint returns 200 with the updated record. Если хочется сослаться на источник ожидания — это отдельное предложение: The API reference says this endpoint returns 200 on success.

Actual — это цитата, а не пересказ. It shows an error бесполезно. Нужен точный текст: код статуса, тело ответа, идентификатор запроса, первая строка стектрейса. Текстом, а не скриншотом: по скриншоту нельзя искать, нельзя скопировать в grep и его не прочитает человек со скринридером. Про то, как читать и цитировать чужие ошибки и логи, — глава Сообщения об ошибках и логи.

Environment — цифры, а не прилагательные. Latest version — худший ответ на вопрос о версии: «последняя» у вас и у читателя это разные сборки, и через месяц строка станет ложью. Здесь же классический ложный друг: actual version по-русски значит «актуальная», а по-английски читается «фактическая» и никак не означает «текущая». Нужное слово — current. Окружение проще не описывать словами, а собирать командой:

# Собрать окружение одной командой и приложить вывод к тикету:
# так исключаются опечатки в номерах версий и споры про «последнюю» сборку
{
  echo "app:     $(myapp --version)"
  echo "os:      $(uname -srm)"
  echo "runtime: $(node --version 2>/dev/null || echo 'n/a')"
  echo "commit:  $(git rev-parse --short HEAD)"
} | tee environment.txt

Notes — место для гипотез, и только там. Всё, чего вы не проверили, живёт в этом блоке и помечено как непроверенное. Почему это отдельная дисциплина — ниже.

Отделять наблюдение от догадки

Это самое ценное умение в баг-репорте и одновременно то, что хуже всего переносится из русского. В русском гипотезу часто маркируют интонацией и вводными словами («да там наверняка кэш»), а при переводе интонация теряется, и остаётся голое утверждение: This is a caching problem. Читатель принимает его за факт, идёт проверять кэш, теряет полдня и возвращается недовольным.

Лестница уверенности в формулировках баг-репорта

Английский маркирует степень уверенности модальностью и структурой предложения, и делает это жёстче русского. Работают три средства.

Модальные глаголы. may, might, could понижают уверенность примерно до «возможно»; should в предположении означает «по идее должно» и часто звучит как претензия; must — уже разобранный случай нормативного требования. Практическая разница: This might be a caching issue — гипотеза, This should be a caching issue — странно, This is a caching issue — утверждение факта, за которое вы отвечаете.

Глаголы восприятия. seems, appears, looks like переводят фразу из режима факта в режим наблюдения: The response appears to come from cache — «выглядит так, что». Носитель прочитает это как «я вижу признаки, но не доказал». Это честнее, чем is, и мягче, чем ничего не говорить.

Прямое признание границы проверки. Самая сильная и самая недооценённая конструкция — просто сказать, чего вы не делали: I have not checked whether…, I could not reproduce this on staging, I only tested with the EU tenant. Никакой модальности не нужно, граница знания названа явно. Русскоязычные инженеры часто избегают таких фраз, опасаясь выглядеть некомпетентно; эффект ровно обратный — читатель видит человека, который различает, что он знает и что предполагает.

Опасен левый верхний квадрант — уверенное утверждение без проверки. Правый нижний тоже стоит денег: если вы проверили, но написали maybe, читатель перепроверит за вами. Хедж должен быть пропорционален незнанию, а не вежливости.

Задача — это не баг

Для задачи (feature, task, chore) структура другая, потому что другой вопрос у читателя. У бага вопрос «что сломано»; у задачи — «что должно стать правдой, когда всё готово». Отсюда правило формулировки: задача описывает результат, а не действие.

  • Refactor the payment module — действие. Непонятно, когда закончится и как проверить.
  • Payment retries are capped at three attempts per minute — результат. Проверяемо, спорить можно по существу.

Заголовок задачи в английском обычно пишут либо повелительным наклонением как команду репозиторию (Add rate limiting to payment retries — тот же стиль, что в сообщениях коммитов, см. Коммиты и pull request), либо декларацией результата в present simple. Смешивать в одном трекере не стоит: список выглядит неряшливо и хуже сканируется.

Критерии приёмки на английском чаще всего пишут в форме Gherkin, и это редкий случай, когда грамматика действительно важна — потому что фразы парсятся инструментами и читаются вслух на груминге:

Feature: Access token refresh
  # Given — состояние до действия: артикль "a" вводит нового участника,
  # дальше по тексту этот же участник идёт с "the"
  Scenario: Refreshing a token that has already expired
    Given a user with a refresh token that expired 10 minutes ago
    When the client sends POST /v1/auth/refresh
    Then the API responds with 401
    And the response body contains the code "token_expired"

Три языковые вещи, которые здесь стоит заметить. Первое: Given — это состояние, поэтому глагол в прошедшем или в форме причастия (a token that expired), а не последовательность действий. Второе: When — ровно одно действие, present simple, третье лицо (sends, не send). Третье: Then — наблюдаемый результат, тоже present simple; распространённая калька Then the API should respond with 401 формально принята во многих командах, но should снова тащит за собой оттенок требования — декларативное responds точнее. Содержательная сторона критериев приёмки — в главе Критерии приёмки, а форматы user story — в Анализ в Agile.

Отдельно про шаблон As a <role>, I want <feature> so that <benefit>. Он полезен, когда роль и польза действительно неочевидны. Он звучит фальшиво и раздражает, когда им оборачивают техническую задачу: As a developer, I want to upgrade the library so that the library is upgraded — реальная строчка из реального бэклога, и таких много. Если польза не формулируется без тавтологии — шаблон не нужен, пишите задачу декларацией результата.

Жизненный цикл: что означают слова на кнопках

Статусы и резолюции трекера — это готовые английские формулировки, которые вы будете и читать, и писать. У каждой есть точное значение и социальный вес, который русскоязычные инженеры часто недооценивают.

duplicate — нейтрально, но требует ссылки: Closing as a duplicate of #482 — the root cause is the same. Без ссылки читается как «отстань». То же с автоматическим stale: закрытие по таймауту допустимо только с оговоркой This is not a judgement on the report — please comment and it will be reopened.

wontfix — самая резкая из резолюций: буквально «не будем чинить», и без объяснения она портит отношения с внешним репортёром. Принято сопровождать причиной и оговоркой: Closing as wontfix for now — the workaround in #514 covers the reported case, and the fix would require breaking the public API. Happy to revisit if more users hit this. Здесь работают for now и happy to revisit: они превращают отказ из окончательного в пересматриваемый, ничего при этом не обещая.

not reproducible / cannot reproduce — тут важно не написать так, будто вы обвиняете репортёра во лжи. Разница между I cannot reproduce this и This does not happen огромна: первое — про вас и вашу попытку, второе — про мир и звучит как «вы выдумали». Рабочая формулировка называет, что именно вы пробовали: I could not reproduce this on 4.2.1 with a clean profile, 10 attempts. Could you check whether it still happens on the current build and share the request id?

works as intended (WAI) — уместно, только если поведение действительно задокументировано. Если оно нигде не описано, WAI читается как «нам лень», и по существу это баг документации: The behaviour is intentional, but it was not documented — I opened #620 to fix the docs.

Как просить недостающую информацию

Отдельный навык — попросить факты так, чтобы человек их прислал, а не обиделся и ушёл. Три приёма, каждый со своей причиной:

  • Спрашивать конкретное, а не «подробности». Could you add more details? перекладывает работу обратно и почти всегда получает такой же расплывчатый ответ. Работает список: Two things would help: the exact error text and the app version from Settings → About.
  • Называть, зачем. I need the request id to find the trace on our side — человек понимает, что его не гоняют по кругу, и находит id охотнее.
  • Не начинать с обвинения. You did not provide the steps (вы не предоставили) — обвинительная конструкция во втором лице. The steps are missing или I could not tell from the description how to get to that screen описывают ситуацию, а не проступок. Механика «сказать про работу, а не про человека» подробно разобрана в главе Обратная связь, а её применение к ревью — в следующей главе трека.

Срочность: как эскалировать по-английски

ASAP, urgent, please fix quickly не ускоряют ничего. Причина не в вежливости: эти слова не содержат информации, по которой можно принять решение о приоритете. Приоритет считается из трёх вещей — что не работает, у скольких, до какого момента это терпит. Формулируйте их, и срочность возникнет сама:

  • This blocks the 4.2 release: QA cannot sign off on checkout until it is fixed. Code freeze is on Thursday.
  • All EU tenants are affected — about 2 300 accounts. Users can still pay through the old flow, so there is a workaround.
  • This is a regression: it worked in 4.1.7 and broke in 4.2.0.

Слово regression — одно из немногих, которое действительно поднимает приоритет само по себе, потому что означает «мы это уже умели и сломали». Так же работает blocker в его процессном смысле: «дальше нельзя двигаться». Оба слова стоит употреблять точно: если вы называете блокером то, что блокером не является, в следующий раз вам не поверят — а других способов сказать «правда очень срочно» у вас нет.

Кальки и ложные друзья, которые встречаются в тикетах чаще всего

Ниже — не словарь, а разбор конкретных строк, которые действительно приходят в трекеры от русскоязычных инженеров. У каждой: что написано, как это читает получатель, как переписать.

Написано Как читается Как надо
actual version 4.2 «фактическая версия» — читатель ищет, чему она противопоставлена current version 4.2
I will realize this feature «я осознаю эту функциональность» I will implement this feature
We need to decide this problem «принять решение по проблеме» вместо «решить» We need to solve this problem
Please control the queue length control = управлять, а не наблюдать Please monitor the queue length
incorrect work of the service work не значит «функционирование» the service returns wrong totals
The bug reproduces on staging reproduce в английском переходный: баг сам себя не воспроизводит The bug is reproducible on staging / I can reproduce it on staging
on production предлог не тот, идиома фиксированная in production
Sorry for my bad English привлекает внимание к языку вместо содержания и снижает вес сообщения ничего не писать
informations, feedbacks, advices эти существительные неисчисляемые, множественное число невозможно information, feedback, advice
It is not working normally normally = «в обычном режиме», а не «нормально» It fails with a 500 on every second request
How I can reproduce it? порядок слов утвердительный в вопросе How can I reproduce it?
We must fix it (в описании бага) must = нормативное требование по RFC 2119 This needs to be fixed before the release
Please, fix it asap запятая после Please — русская пунктуация, asap — давление без информации This blocks the release on Thursday

Про артикли отдельно и честно. В тикетах они ломают смысл редко — и именно поэтому не стоит тратить на них основные силы. Практический минимум, который закрывает большинство случаев: первое упоминание объекта — a/an, все последующие — the (I created a report; the report was empty); единственные в системе сущности — всегда the (the database, the API, the main branch); имена собственные и продукты — без артикля (Postgres, Kafka, Chrome); неисчисляемые — без артикля (traffic, latency, data, memory). Одно место, где артикль действительно меняет смысл и стоит проверки: I checked the log (тот самый, о котором речь) против I checked a log (какой-то один из многих) — во втором случае читатель обязан спросить, какой именно. Систематический разбор ошибок русскоязычных инженеров — в главе Типичные ошибки.

Шаблон, который делает часть работы за вас

Шаблон не научит писать, но он делает пропуск факта заметным. В GitHub для этого есть issue forms — YAML-описание формы с обязательными полями; в отличие от markdown-шаблонов, поля нельзя молча стереть. Документация — Configuring issue templates.

# .github/ISSUE_TEMPLATE/bug_report.yml
name: Bug report
description: Report a reproducible defect
title: "bug: "                      # префикс подставится в заголовок автоматически
labels: ["bug", "needs-triage"]
body:
  - type: input
    id: version
    attributes:
      label: Version
      description: Exact build you observed this on, not "latest"
      placeholder: "4.2.1 (build 3921)"
    validations:
      required: true                # без версии форму не отправить
  - type: textarea
    id: steps
    attributes:
      label: Steps to reproduce
      description: One action per line, starting from a known state
      value: |
        1.
        2.
        3.        
    validations:
      required: true
  - type: textarea
    id: actual
    attributes:
      label: Actual result
      description: Paste the exact error text or status code, not a screenshot
    validations:
      required: true
  - type: dropdown
    id: frequency
    attributes:
      label: How often does it happen?
      options:                      # частота отвечает на вопрос «стоит ли ловить гонку»
        - Every time
        - Occasionally
        - Once, could not reproduce again
    validations:
      required: true

Шаблон закрывает пропуски, но не качество формулировок. Перед отправкой проще прогнать текст по пяти вопросам:

  1. Первые 60 символов заголовка содержат компонент и наблюдаемый глагол?
  2. Может ли человек, впервые видящий систему, дойти по шагам от известного состояния до поломки?
  3. Текст ошибки приведён текстом, а не картинкой, и версия указана числом, а не словом latest?
  4. Каждая догадка помечена как догадка (might, appears, I have not checked)?
  5. Если тикет закрывают вопросом — какой это вопрос? Ответьте на него заранее.

Особые случаи, где обычные правила не работают

Уязвимость не публикуют в трекере. Публичный issue с воспроизведением уязвимости — это раздача эксплойта. Английский тут ритуализирован: ищется SECURITY.md, приватный advisory или адрес вида security@, а первое сообщение короткое и без деталей: I would like to report a possible security issue in the authentication flow. Could you confirm the right private channel? Контекст — трек Безопасность.

Инцидент — не баг. Во время инцидента пишут в канал коротко, в present continuous, с временными метками и без гипотез: Checkout is returning 503 for all regions since 14:20 UTC. Investigating. Баг заводится потом, из постмортема, и в нём уже past simple. Разница жанров разобрана в Постмортемах.

Баг в чужой опенсорс-библиотеке. Вы просите об одолжении у человека, который делает это бесплатно: никаких сроков и требований. Обязателен минимальный воспроизводимый пример (в английском его устойчиво зовут MCVE — minimal complete verifiable example): не проект целиком, а двадцать строк, которые падают. Нормы таких обращений разобрал Эрик Реймонд в «How To Ask Questions The Smart Way»; плюс строчка, сразу поднимающая ваш статус в глазах мейнтейнера: Searched the existing issues and did not find this.

Баг, который вы не можете воспроизвести. Соблазн — не заводить вовсе. Правильнее завести и честно сказать об этом в заголовке и теле: Intermittent 502 on checkout — could not reproduce reliably (3 occurrences in 2 weeks). Слово intermittent — точный отраслевой термин для «плавает», а числа в скобках превращают «иногда» в данные. Плюс всё, что есть: время каждого случая, request id, любые совпадения. Такой тикет полезен: следующий человек с тем же симптомом найдёт его поиском и добавит свои три случая.

Мини-итог

  • Критерий качества тикета один: исполнитель начинает работу, не задав ни одного вопроса. Грамматика вторична, полнота — нет.
  • Заголовок и тело — два разных текста. Заголовок пишется для триажера, который не откроет тикет: компонент, наблюдаемый глагол, условие, всё в первых 60 символах.
  • Глагол в заголовке — это уже диагноз: times out, crashes, returns stale data направляют разных людей в разные места. doesn't work не направляет никуда.
  • Present simple означает «воспроизводится», past simple — «был единичный случай». Перепутанное время меняет судьбу тикета.
  • Steps — императив, по одному действию на строку; Expected/Actual — present simple, без must: оно занято нормативным смыслом из RFC 2119. Actual — точная цитата ошибки текстом, а не скриншот; версия — числом, latest не является версией.
  • Догадка помечается модальностью (might, appears to) или прямым признанием границы (I have not checked…): уверенное утверждение без проверки — самая дорогая ошибка.
  • Задача описывает результат, а не действие. As a…, I want… не обязателен и вреден там, где польза формулируется тавтологией.
  • Резолюции — это слова с весом: wontfix без объяснения ломает отношения, cannot reproduce формулируется про себя (I could not reproduce), а не про репортёра.
  • Срочность выражается фактами — что сломано, у скольких, до какого срока, — а не словами urgent и ASAP. regression и blocker работают, пока употребляются точно.

Материалы

Что дальше

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

Комментарии на ревью: как сказать «нет» и не обидеть

Нашли неточность? Выделите фрагмент текста — рядом появится жучок.

Нужен разбор именно вашей ситуации?

Статья описывает общий случай. Если у вас частный — можно разобрать его отдельно, платно. А если не хватает целого материала, предложите тему: её оплачивают вскладчину, и она выходит открытой для всех.

Доска запросов