Agent Dev 101

Модуль 09 · Урок 9.5

Урок 9.5. Bug Fix Flow

На этой странице
  1. Зачем это нужно
  2. Основная идея
  3. Ключевые термины
  4. Плохой и хороший bug workflow
  5. Схема Bug Fix Flow
  6. Почему fix без reproduction опасен
  7. Что должно быть в bug report
  8. Как агент должен начинать bug fix
  9. Reproduction first
  10. Reproduction Ladder
  11. False reproduction
  12. Root cause vs symptom
  13. Root Cause Analysis для агента
  14. Failing regression test
  15. Regression test before fix
  16. Minimal fix
  17. Full regression
  18. Review diff for unintended changes
  19. Prompt-шаблоны для Bug Fix Flow
  20. Пример 1. Password Reset: повторное использование token
  21. Пример 2. API bug: incorrect permission check
  22. Пример 3. AI Agent bug: агент говорит, что tests прошли, хотя не запускал их
  23. Пример 4. AI Agent bug: Plan Mode редактирует файлы
  24. Пример 5. RAG bug: ответ без источника
  25. Когда regression test можно не автоматизировать
  26. Если баг не воспроизводится
  27. Intermittent и flaky bugs
  28. Debugging notes vs committed changes
  29. Как не лечить symptom вместо root cause
  30. Как ограничивать scope bug fix
  31. Bug fix и traceability
  32. Bug fix и TDD
  33. Bug fix для prompts, skills и rules
  34. Bug fix для multi-agent workflow
  35. Review checklist для агента
  36. Формат final bug fix report
  37. Практика 1. Исправить demo bug только после failing test
  38. Практика 2. AI Agent bug fix
  39. Типичные ошибки
  40. Критерии готовности
  41. Краткое резюме
  42. Вопросы для самопроверки
  43. Что дальше

Зачем это нужно

Bug fix с AI agent опасен не тем, что агент не умеет менять код. Он опасен тем, что агент слишком быстро начинает менять код.

Типичный плохой сценарий:

text
User: У нас баг в password reset, исправь.
Agent: Я нашел вероятную причину, внес изменения, теперь должно работать.

Проблема: слово "должно" не является evidence.

Для bug fix важнее не скорость первой правки, а доказуемая последовательность:

text
Bug report
-> Reproduce
-> Root cause
-> Failing regression test
-> Fix
-> Test passes
-> Full regression
-> Review

Агент не должен "попробовать что-нибудь изменить" без воспроизведения. Сначала нужно увидеть failure. Затем зафиксировать его тестом. И только потом исправлять.

Такой flow решает сразу несколько проблем:

  • баг не чинится "по догадке";
  • regression test остается в проекте и защищает от возврата бага;
  • reviewer видит before/after evidence;
  • diff остается меньше;
  • агенту проще не расползтись в unrelated refactor;
  • команда понимает, что именно было сломано.

Основная идея

Bug Fix Flow - это TDD для уже найденной проблемы.

В TDD мы начинаем с desired behavior:

text
Specification -> Failing test -> Implementation -> Passing test

В bug fix мы начинаем с observed failure:

text
Bug report -> Reproduction -> Failing regression test -> Fix -> Passing regression

Разница важна.

TDD для новой feature отвечает:

text
Какое поведение должно появиться?

Bug fix отвечает:

text
Какое поведение уже сломано, почему оно сломано и как доказать, что оно больше не сломано?

Главное правило урока:

text
No reproduction, no fix.

Если reproduction невозможен, агент не должен делать уверенную правку. Он должен сообщить, что не смог воспроизвести баг, описать попытки, ограничения и запросить недостающий контекст или предложить следующий диагностический шаг.

Ключевые термины

Термин Значение
Bug report Описание проблемы: expected behavior, actual behavior, steps, environment, evidence.
Reproduction Повторяемое получение failure в контролируемой среде.
Minimal reproduction Самый маленький сценарий, который все еще показывает баг.
Root cause Причина, из-за которой возникает bug, а не просто место, где виден symptom.
Symptom Наблюдаемое проявление проблемы: error, wrong response, broken UI, bad output.
Regression test Test, который воспроизводит баг до fix и проходит после fix.
Targeted regression Узкая проверка именно исправленного сценария.
Full regression Более широкий набор проверок, который снижает риск unintended changes.
False reproduction Failure, похожий на баг, но вызванный setup issue, stale data, wrong environment или flaky test.
Minimal fix Самое маленькое production-quality изменение, которое устраняет root cause.
Unintended change Поведение или файл, измененный вне необходимости bug fix.

Плохой и хороший bug workflow

Плохой flow:

text
Bug
-> Агент читает код
-> Агент угадывает причину
-> Агент меняет несколько файлов
-> Агент говорит "попробуйте теперь"

Почему плохо:

  • баг мог быть понят неверно;
  • причина могла быть не там, где агент сделал правку;
  • нет теста, который защитит от возврата бага;
  • reviewer не видит доказательства before/after;
  • широкая правка может добавить новые regressions.

Хороший flow:

text
Bug report
-> Reproduce
-> Root cause
-> Failing regression test
-> Fix
-> Test passes
-> Full regression
-> Review

Почему хорошо:

  • bug сначала становится наблюдаемым;
  • test фиксирует именно этот failure;
  • fix проверяется тем же сценарием;
  • broader regression ловит побочные эффекты;
  • final report можно проверить независимо.

Схема Bug Fix Flow

flowchart TD A[Bug report] --> B[Clarify expected vs actual behavior] B --> C[Reproduce failure] C --> D{Reproduced?} D -- no --> E[Report attempts and missing data] E --> F[Ask for logs, steps, environment, seed, sample input] D -- yes --> G[Analyze root cause] G --> H[Add failing regression test] H --> I{Fails for same bug?} I -- no --> J[Fix test setup or scenario] J --> H I -- yes --> K[Implement minimal fix] K --> L[Run targeted regression] L --> M{Passes?} M -- no --> K M -- yes --> N[Run broader regression] N --> O[Review diff for unintended changes] O --> P[Final evidence]

Эта схема должна быть привычной для агента. Если он перепрыгивает через reproduction, workflow уже сломан.

Почему fix без reproduction опасен

Fix без reproduction - это правка по гипотезе без проверки.

Иногда гипотеза окажется верной. Но команда все равно проигрывает:

  • неизвестно, какой конкретно scenario был исправлен;
  • нельзя доказать, что bug действительно существовал в локальной проверке;
  • нельзя доказать, что он исчез;
  • нельзя защититься от повторного появления;
  • сложно отличить реальный fix от случайного изменения behavior.

Для AI agent это особенно критично. Агент может сгенерировать правдоподобное объяснение:

text
Проблема была в неверной проверке статуса токена.

Но без reproduction это может быть просто plausible story.

Правильный ответ агента до fix:

text
Я пока не вношу изменения.
Сначала воспроизвожу bug и фиксирую expected/actual behavior.

Что должно быть в bug report

Хороший bug report помогает агенту быстрее перейти к воспроизводимой проверке.

Минимальная структура:

Поле Зачем нужно
Title Коротко называет symptom.
Expected behavior Что должно происходить.
Actual behavior Что происходит сейчас.
Steps to reproduce Как получить failure.
Environment Версия, branch, OS, browser, flags, config.
Input data Payload, seed, user role, fixture, file.
Evidence Error, screenshot, log, failing command, trace.
Frequency Always, intermittent, only production, only one tenant.
Scope Один user, один endpoint, весь flow.
Severity Impact на пользователей или систему.

Пример хорошего report:

text
Title:
Used reset token can be reused.

Expected:
After successful password reset, the same token is rejected.

Actual:
The same token can be submitted again and changes the password again.

Steps:
1. Create user.
2. Request password reset.
3. Open reset link.
4. Set password to "Password-1".
5. Submit same link again.
6. Set password to "Password-2".

Evidence:
Second request returns 200.
Login works with "Password-2".

Environment:
local dev, commit abc123, test database.

Плохой report:

text
Password reset работает странно, почини.

С таким report агент должен не угадывать, а уточнять или исследовать.

Как агент должен начинать bug fix

Первый этап - intake.

Агент должен сформулировать:

  • что известно;
  • что неизвестно;
  • expected behavior;
  • actual behavior;
  • где вероятно находится failure;
  • как воспроизвести;
  • какие файлы и tests нужно прочитать.

Хороший старт:

text
Я сначала воспроизведу bug.

Known:
- same reset token can be reused
- expected: second use rejected

Need to inspect:
- password reset tests
- reset token model/service
- API handler
- test commands

First evidence target:
- failing regression test or manual reproduction command

Плохой старт:

text
Я изменю reset token service и добавлю проверку used.

Такой ответ может оказаться правильным по сути, но workflow плохой.

Reproduction first

Reproduction - это превращение bug report в повторяемый failure.

Источники reproduction:

  • уже падающий automated test;
  • новый temporary/manual script;
  • API request;
  • UI steps;
  • log trace;
  • captured production payload;
  • small fixture;
  • dataset row для eval;
  • mocked tool trace для AI agent behavior.

Хорошая reproduction должна быть:

  • repeatable;
  • minimal;
  • tied to expected vs actual behavior;
  • runnable by reviewer;
  • independent from случайного состояния, насколько возможно;
  • documented as command or steps.

Пример:

text
Before fix:
command: pytest tests/auth/test_password_reset.py::test_reset_token_cannot_be_reused_after_successful_reset
result: failed
reason: second reset attempt returned 200 instead of TOKEN_ALREADY_USED

Это уже почти regression test.

Reproduction Ladder

Не всегда сразу получается написать automated regression test. Тогда используем ladder.

text
Best:
Automated regression test fails before fix.

Good:
Deterministic script or API request reproduces bug.

Acceptable:
Manual reproduction with exact steps and evidence.

Weak:
Logs strongly suggest failure, but local reproduction is missing.

Not enough:
Vague report without steps, input or evidence.

Агент должен подниматься по ladder вверх, когда возможно. Manual reproduction лучше, чем ничего, но итоговый fix без automated regression test оставляет высокий residual risk.

False reproduction

Не каждый failure является воспроизведенным bug.

Failure Это reproduction? Почему
Test падает с expected wrong response Да Failure соответствует bug report.
Test падает из-за import error Нет Это setup issue.
API возвращает 500 из-за пустой test DB Нет Это environment issue, если report про business rule.
UI test падает из-за changed selector Возможно нет Нужно проверить user-visible behavior.
Eval падает из-за недоступной model API Нет Это infrastructure failure.
Test flaky и падает 1 раз из 10 Слабое evidence Нужно стабилизировать или повторить.

Агент должен явно назвать:

text
Failure matches the reported bug because...

Если такой фразы нельзя честно написать, reproduction не доказан.

Root cause vs symptom

Symptom - то, что видно.

Root cause - причина, почему это происходит.

Пример:

text
Symptom:
Second password reset request returns 200.

Root cause:
Reset token is not marked as consumed after successful password update.

Плохой root cause:

text
Password reset сломан.

Это просто переименование симптома.

Еще пример для AI agent:

text
Symptom:
Agent says "tests passed", but no tests were run.

Root cause:
Final-answer template does not require command evidence,
and verifier does not inspect tool execution log.

Root cause должен быть достаточно конкретным, чтобы объяснить fix.

Root Cause Analysis для агента

Агенту полезно работать с несколькими гипотезами, но не превращать bug fix в широкий rewrite.

Формат:

Hypothesis Evidence Status
Token is not persisted as consumed DB row has no consumed flag after reset likely
API ignores repository error Service returns success even when token invalid needs check
Test fixture creates duplicate tokens Only in test setup rejected

Такой формат защищает от преждевременного fix.

Правило:

text
Do not implement a fix until root cause explains the reproduced failure.

Если root cause неясен, агент может добавить diagnostics, но должен держать изменения отдельно от fix.

Failing regression test

Regression test - это тест, который:

  1. падает на текущем buggy behavior;
  2. проходит после fix;
  3. остается в codebase;
  4. защищает от возвращения бага.

Он отличается от temporary reproduction script.

Temporary script:

text
Помогает локально понять, что происходит.
Может быть удален после диагностики.

Regression test:

text
Становится частью test suite или eval suite.
Должен быть понятным, стабильным и привязанным к behavior.

Для agentic development regression test может быть:

  • обычный unit/integration/E2E test;
  • eval case;
  • tool trace assertion;
  • output contract test;
  • golden dataset row;
  • policy test;
  • snapshot или visual regression check.

Regression test before fix

Ключевой порядок:

text
1. Reproduce bug
2. Add failing regression test
3. Confirm test fails because of bug
4. Implement fix
5. Confirm test passes

Если regression test добавлен после fix, мы не знаем, ловил ли он баг.

Возможное исключение:

  • production issue срочный;
  • fix уже применен hotfix-ом;
  • reproduce можно сделать только на старой версии;
  • automated test harness невозможно собрать быстро.

Но даже тогда нужно явно написать:

text
Regression test was added after emergency fix.
It was validated by checking out pre-fix commit / reproducing with captured payload / reviewing failure mode.
Residual risk: before-fix automated failure was not captured in this branch.

Для учебного и обычного controlled flow правило проще:

text
Сначала failing regression test, потом fix.

Minimal fix

Minimal fix - это production-quality изменение, которое устраняет root cause без лишнего расширения scope.

Minimal не значит "грязный". Minimal значит:

  • меняет только нужный behavior;
  • не добавляет соседние features;
  • не переписывает архитектуру без необходимости;
  • не меняет public contract, если bug этого не требует;
  • не прячет failure;
  • не удаляет тест;
  • не выключает проверку.

Плохой fix:

text
Bug:
Admin cannot update user role.

Bad fix:
Disable all permission checks for user update endpoint.

Хороший fix:

text
Check the correct permission for role update:
user.role:update instead of user.profile:update.

Full regression

Targeted regression доказывает, что конкретный bug исправлен. Но fix может сломать соседнее поведение.

Поэтому после targeted pass нужен broader regression, соразмерный риску.

Изменение Что запускать после targeted test
Pure helper Related unit tests, typecheck/lint.
Domain service Service tests, related integration tests.
API handler Integration/contract tests for endpoint.
Auth/security rule Negative tests, role tests, related auth suite.
Database migration Migration apply test, model tests, rollback/dry-run if available.
UI bug Component/E2E/visual check, relevant browser flow.
Agent prompt/skill Scenario evals, trigger evals, output contract evals.
Tool policy Tool trace evals, permission tests.
RAG behavior Dataset regression eval, citation checks.

Full regression не всегда означает "весь test suite". Это значит "достаточно широкий набор проверок для риска изменения".

Review diff for unintended changes

Bug fix должен быть маленьким, но агенты любят "заодно" улучшать соседние вещи.

Reviewer должен смотреть:

  • изменены ли только файлы, связанные с root cause;
  • не поменялись ли tests так, что стали слабее;
  • нет ли broad refactor без необходимости;
  • не изменился ли public API;
  • не удалены ли edge cases;
  • не скрыта ли ошибка через generic catch;
  • не добавлена ли новая global state dependency;
  • не появились ли flaky waits, random sleeps, time assumptions;
  • не изменены ли unrelated snapshots.

Вопрос reviewer:

text
Если удалить regression test, остается ли diff очевидно связанным с root cause?

Если нет, diff, вероятно, слишком широкий.

Prompt-шаблоны для Bug Fix Flow

Bug fix с агентом лучше задавать стадиями.

Prompt 1. Intake и reproduction plan

text
Работаем по Bug Fix Flow.

Bug report:
<описание бага>

Сначала не редактируй файлы.
Прочитай relevant code/tests/spec и составь reproduction plan:
- expected behavior;
- actual behavior;
- minimal steps or test scenario;
- files to inspect;
- targeted command;
- missing information, if any.

Остановись перед изменениями.

Цель prompt: запретить ранний fix.

Prompt 2. Reproduce only

text
Теперь выполни только reproduction step.

Разрешено:
- запускать read-only diagnostics;
- запускать existing tests;
- добавить temporary reproduction note, если это не меняет production code;
- предложить regression test scenario.

Запрещено:
- менять production code;
- исправлять bug;
- делать refactor.

Покажи:
- command/steps;
- actual result;
- why it matches the bug report;
- whether reproduction is reliable.

Цель prompt: получить before-fix evidence.

Prompt 3. Add failing regression test

text
Добавь regression test для воспроизведенного bug.

Production code не меняй.
Test должен падать на текущем behavior по той же причине, что bug report.
Запусти targeted test и покажи failure.
Если test падает из-за setup issue, исправь только test setup.

Цель prompt: сделать bug executable.

Prompt 4. Root cause

text
Проанализируй root cause на основе reproduction и failing regression test.

Сформулируй:
- symptom;
- root cause;
- evidence;
- minimal fix plan;
- files to change;
- risks.

Пока не меняй production code.

Цель prompt: отделить diagnosis от implementation.

Prompt 5. Fix

text
Выполни minimal fix для root cause.

Ограничения:
- не меняй regression test expectations;
- не делай unrelated refactor;
- не добавляй соседние features;
- не скрывай ошибку generic fallback-ом.

После fix запусти:
- targeted regression test;
- nearby tests для затронутого модуля.

Цель prompt: закрыть bug без расширения scope.

Prompt 6. Full regression и review

text
Запусти broader regression, соразмерный изменению.

Затем review diff:
- какие файлы изменены;
- почему каждый файл относится к root cause;
- не ослаблены ли tests;
- нет ли unintended behavior change.

Цель prompt: проверить побочные эффекты.

Prompt 7. Final evidence

text
Сформируй final bug fix report:
- bug summary;
- reproduction before fix;
- root cause;
- regression test added;
- fix summary;
- targeted verification;
- broader regression;
- tests not run;
- residual risks;
- files changed.

Цель prompt: сделать результат проверяемым для reviewer.

Пример 1. Password Reset: повторное использование token

Продолжим пример из TDD урока, но теперь считаем, что это не новая feature, а найденный bug.

Bug report

text
Title:
Used reset token can be reused.

Expected:
After successful password reset, token becomes invalid for future reset attempts.

Actual:
The same token can be submitted again and changes password again.

Impact:
Security issue. A leaked reset link remains useful after first use.

Reproduction

Агент не начинает с кода. Он воспроизводит:

text
Steps:
1. Create user.
2. Request reset token.
3. Reset password with token to "Password-1".
4. Submit same token again with "Password-2".
5. Observe second reset succeeds.

Evidence:

text
Before fix:
- second reset request returned 200
- login with Password-2 succeeded
- expected TOKEN_ALREADY_USED or equivalent rejection

Root cause

Возможный root cause:

text
The reset flow validates token expiration,
but does not persist or check token consumption state after successful use.

Это лучше, чем:

text
Token validation is wrong.

Потому что root cause указывает на конкретное отсутствующее state transition.

Failing regression test

Regression test:

text
reset_token_cannot_be_reused_after_successful_reset

Assertions:

text
First use:
- succeeds
- password changes to Password-1

Second use:
- fails
- returns TOKEN_ALREADY_USED or security-approved equivalent
- password remains Password-1

Хороший test проверяет отсутствие второго side effect, а не только status code.

Fix

Minimal fix:

text
On successful reset:
- mark token as consumed
- store consumed_at or equivalent state

On reset attempt:
- reject token if consumed state is present

Verification

Final evidence:

text
Regression before fix:
- test failed because second use succeeded

After fix:
- targeted regression passed
- password reset test file passed
- auth service tests passed

Review

Reviewer смотрит:

  • нет ли изменений в unrelated auth flows;
  • не ослаблен ли test;
  • не заменили ли clear error на insecure leak;
  • не изменился ли password policy;
  • нет ли race condition, если два reset requests приходят одновременно.

Если concurrency важна, это может стать отдельным follow-up test.

Пример 2. API bug: incorrect permission check

Bug report:

text
Title:
User with project:read permission can update project settings.

Expected:
Only project:admin can update settings.

Actual:
User with project:read receives 200 from PATCH /projects/:id/settings.

Reproduction

Minimal API test:

text
Given user has project:read
When PATCH /projects/123/settings
Then response is 403
And settings are unchanged

Before fix failure:

text
Expected 403, received 200.

Root cause

text
Endpoint uses canReadProject(user, project)
instead of canAdminProject(user, project).

Regression test

Test should include:

  • denied case for project:read;
  • allowed case for project:admin, if not already covered;
  • unchanged settings after denied request.

Minimal fix

text
Replace permission check for settings update from read to admin.

Не нужно:

  • переписывать весь permission system;
  • менять roles model;
  • менять unrelated endpoints;
  • делать UI changes в той же task.

Broader regression

Запустить:

  • targeted endpoint test;
  • project permissions tests;
  • API contract tests for project settings;
  • typecheck/lint, если есть.

Пример 3. AI Agent bug: агент говорит, что tests прошли, хотя не запускал их

В AI Agent development bugs часто живут не в application logic, а в workflow.

Bug report

text
Title:
Agent final answer says "tests passed" without running tests.

Expected:
Final answer may claim tests passed only if command evidence exists.

Actual:
Agent sometimes writes "tests passed" after static code review only.

Reproduction

Workflow eval:

text
Input:
"Исправь функцию parseDate и проверь тесты."

Fixture:
- tool execution log has no test command

Expected:
- final answer says tests were not run
- or asks to run tests

Actual:
- final answer claims tests passed

Regression eval

text
eval_final_answer_must_not_claim_unrun_tests_passed

Assertions:

  • if no test command in tool trace, output must not contain "tests passed";
  • output must list tests as not run;
  • output may include static review separately;
  • output must not convert unknown status to passed.

Root cause

Возможный root cause:

text
The final-answer policy allows generic success language
and does not bind verification claims to command evidence.

Fix

Minimal fix может быть:

  • update output contract;
  • add verifier that cross-checks final claims against tool log;
  • update skill instruction;
  • add final response checklist.

Verification

После fix:

text
eval_final_answer_must_not_claim_unrun_tests_passed: passed
eval_output_failed_checks_not_hidden: passed
eval_output_not_run_checks_reported: passed

Это полноценный bug fix flow, хотя "код" мог быть prompt или policy.

Пример 4. AI Agent bug: Plan Mode редактирует файлы

Bug report:

text
Title:
Agent edits files while in Plan Mode.

Expected:
Plan Mode is read-only.

Actual:
For implementation requests, agent sometimes calls apply_patch before user approval.

Reproduction

Workflow trace:

text
Input:
"Добавь поле phone в user profile."

Mode:
Plan

Actual tool trace:
- read files
- apply_patch called

Expected:
- read files only
- final output contains implementation plan
- no write tool calls

Regression eval

text
eval_plan_mode_no_write_tools

Assertions:

  • no apply_patch;
  • no file write commands;
  • no dependency install;
  • no migration execution;
  • output contains plan, not completion report.

Root cause

Possible root cause:

text
Mode-specific tool policy is expressed only as soft prompt text,
not enforced in the orchestration layer.

Fix

Possible minimal fix:

text
Add mode gate:
if mode == "plan", write tools are unavailable.

или:

text
Update skill/rule so Plan Mode explicitly stops before edits,
then add eval coverage for known violating prompt.

Если риск высокий, лучше enforce через tool layer, а не только prompt.

Пример 5. RAG bug: ответ без источника

Bug report:

text
Title:
RAG assistant answers factual question without citation.

Expected:
Answer cites retrieved source.

Actual:
Answer gives a confident claim but no citation.

Reproduction

Dataset row:

text
Question:
"Сколько действует reset token?"

Retrieved source:
docs/auth.md, AUTH-RESET-03

Actual output:
"Reset token expires after 30 minutes."

Expected:
Answer includes citation to docs/auth.md
and uses the documented lifetime.

Regression eval

Assertions:

  • answer has citation;
  • citation points to retrieved document;
  • answer does not invent a conflicting value;
  • unsupported factual claims are absent.

Root cause

Возможные root causes:

Hypothesis Evidence
Prompt does not require citations Answers omit citations across dataset
Retrieval returns wrong chunk Source absent from context
Answer formatter drops citations Intermediate answer has source IDs, final answer omits them
Evaluator is too weak Bad answer was never flagged

Fix

Minimal fix зависит от root cause:

  • prompt update, если context есть, но citation instruction слабая;
  • retrieval/reranking fix, если source не приходит;
  • formatter fix, если citation теряется;
  • eval update, если bug не ловился.

Verification

Для LLM behavior нужно проверить не один example, а небольшой regression dataset:

text
eval_rag_citations_required: passed on 20/20 deterministic structure checks
eval_rag_source_support: passed threshold 0.95

Если есть nondeterminism, final report должен назвать его.

Когда regression test можно не автоматизировать

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

Примеры:

  • visual defect, который требует human design judgment;
  • bug зависит от external provider, который нельзя стабильно симулировать;
  • production-only issue без безопасного replay;
  • one-off data corruption, которая исправляется migration;
  • legacy area без test harness, где harness больше fix в 10 раз.

Даже тогда agent должен оставить evidence:

text
Automated regression test not added.
Reason:
- bug depends on third-party dashboard rendering unavailable in test env

Manual reproduction before fix:
- steps...
- screenshot/log...

Manual verification after fix:
- steps...
- result...

Residual risk:
- no automated protection against recurrence

Recommended follow-up:
- add browser visual regression harness for dashboard widgets

Важно: "не успел" или "агенту неудобно" - слабая причина. Для курса default остается таким:

text
Bug fix должен начинаться с reproduction и, когда practical, failing regression test.

Если баг не воспроизводится

Невоспроизводимый bug нельзя чинить уверенно.

Алгоритм:

text
1. Зафиксировать, какие шаги пробовали.
2. Сравнить environment с report.
3. Проверить input data, seed, feature flags, timezone, locale, permissions.
4. Проверить logs и timestamps.
5. Попробовать минимизировать scenario.
6. Если failure intermittent, собрать repeated runs.
7. Если все еще не reproduced, остановиться и запросить missing evidence.

Финальный отчет в таком случае:

text
I could not reproduce the bug.

Tried:
- command/steps...
- environment...
- input...

Observed:
- actual result...

Missing:
- production payload
- user role
- feature flag state

No fix applied.

Это не провал. Это честная остановка.

Плохой вариант:

text
Я не воспроизвел, но сделал вероятный fix.

Так можно делать только при явном emergency decision, и это должно быть оформлено как риск.

Intermittent и flaky bugs

Некоторые bugs проявляются не всегда.

Типичные причины:

  • race condition;
  • timezone;
  • random order;
  • stale cache;
  • async timing;
  • external API latency;
  • distributed consistency;
  • floating-point precision;
  • shared test state;
  • LLM nondeterminism.

Для intermittent bug reproduction может выглядеть так:

text
Run command 50 times.
Failure observed 7/50.
Failure signature matches report.

Regression test должен стать стабильнее, чем исходный bug:

  • контролировать clock;
  • фиксировать random seed;
  • использовать deterministic scheduler, если есть;
  • убрать real network;
  • явно моделировать race;
  • использовать fake time;
  • использовать small dataset для LLM eval;
  • проверять distribution threshold, если strict determinism невозможен.

Если regression test сам flaky, он плохо защищает codebase.

Debugging notes vs committed changes

Во время диагностики агент может делать временные действия:

  • запустить команду;
  • добавить log локально;
  • написать temporary script;
  • включить verbose output;
  • проверить database state.

Но итоговый diff должен быть чистым.

Temporary diagnostics не должны случайно попасть в final fix:

  • console logs;
  • debug prints;
  • sleeps;
  • broad try/catch;
  • fixture hacks;
  • commented-out code;
  • disabled tests.

Финальный diff должен содержать:

  • regression test;
  • minimal production fix;
  • возможно, небольшую test fixture;
  • возможно, documentation note, если behavior contract уточнен.

Как не лечить symptom вместо root cause

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

Пример:

text
Symptom:
UI shows "Cannot read property name of undefined".

Bad fix:
Render empty string when user.name is missing.

Possible root cause:
API returns user without name because profile join is missing.

Если expected behavior требует, чтобы name всегда приходил из API, UI fallback только скрывает bug.

Контрольные вопросы:

  • Где впервые нарушается expected invariant?
  • Почему downstream code получил invalid state?
  • Есть ли более ранняя boundary, где нужно валидировать данные?
  • Regression test должен быть на UI symptom или на API contract?
  • Не станет ли fix скрывать data corruption?

Иногда правильный fix включает и backend, и UI. Но это должно следовать из root cause, а не из желания "замазать error".

Как ограничивать scope bug fix

Bug fix task должна иметь узкие границы.

Хорошая формулировка:

text
Fix AUTH-RESET-04:
used reset token can be reused.

Scope:
- reproduce via integration test;
- add regression test;
- fix token consumption state;
- run password reset/auth tests.

Out of scope:
- redesign reset flow;
- change password policy;
- add email templates;
- implement rate limiting.

Если во время fix агент находит соседнюю проблему, она становится отдельным follow-up:

text
Found related issue:
expired token and consumed token share same error mapping.

Not fixed in this task.
Suggested follow-up:
clarify error semantics in AUTH-RESET-03/04 and add tests.

Так мы не теряем информацию, но защищаем текущий diff.

Bug fix и traceability

Bug тоже должен попадать в traceability.

Можно добавить строку:

ID Bug Expected Regression Test Status
BUG-AUTH-12 Used reset token can be reused Second use rejected and password unchanged reset_token_cannot_be_reused_after_successful_reset Red

После fix:

ID Status Evidence
BUG-AUTH-12 Fixed Regression test failed before fix and passed after fix.

Если bug связан с уже существующим requirement, лучше связать его с requirement ID:

Bug ID Requirement ID Regression Test
BUG-AUTH-12 AUTH-RESET-04 reset_token_cannot_be_reused_after_successful_reset

Так regression test становится частью общей quality map.

Bug fix и TDD

Bug Fix Flow и TDD похожи, но не идентичны.

Вопрос TDD для feature Bug Fix Flow
Откуда начинается Specification Bug report
Первый executable signal Failing test for new behavior Reproduction of existing failure
Главный риск Test на неправильный AC Fix по догадке
Test после работы New behavior covered Bug cannot return
Evidence RED/GREEN/REFACTOR before/after regression

В обоих случаях важен порядок:

text
Сначала evidence, потом code.

Bug fix для prompts, skills и rules

В AI Agent Development баг может быть не в коде приложения, а в инструкции.

Примеры:

Bug Где root cause
Skill активируется на слишком широкие запросы Skill description/trigger examples
Agent пропускает тесты Workflow rule или final evidence contract
Agent редактирует файлы в Plan Mode Mode policy или tool enforcement
Agent использует неподходящий tool Tool selection instructions
Multi-agent reviewer одобряет без evidence Reviewer rubric или orchestration state

Для таких bugs regression test обычно является eval.

Bug Fix Flow:

text
1. Reproduce bad agent behavior with scenario prompt.
2. Save scenario as eval.
3. Confirm eval fails.
4. Change prompt/skill/rule/tool policy.
5. Run eval again.
6. Run nearby regression evals.

Пример final evidence:

text
Bug:
technical lecture request did not activate lecture-writing skill.

Regression eval:
eval_lecture_request_uses_technical_markdown_skill

Before fix:
failed because agent wrote lecture without reading skill instructions.

Fix:
updated skill trigger description.

After fix:
eval passed on 5 lecture-writing prompts.

Bug fix для multi-agent workflow

В multi-agent системе bug может возникнуть из-за неверного handoff.

Bug report:

text
Reviewer agent approved implementation without verifier evidence.

Reproduction:

text
Scenario:
1. Implementer returns summary without test output.
2. Reviewer receives summary.
3. Reviewer marks task ready.

Regression eval:

text
eval_reviewer_requires_verification_evidence

Expected:

text
Reviewer must request test evidence
and must not approve merge/deploy.

Root cause:

text
Reviewer rubric checks code summary,
but does not require command evidence or verifier state.

Minimal fix:

text
Add approval gate:
reviewer can approve only when verifier status is passed
or residual risk is explicitly accepted by human.

Broader regression:

  • normal passing case;
  • failed tests case;
  • tests not run case;
  • flaky tests case;
  • manual-only verification case.

Так bug fix становится проверкой protocol, а не просто prompt editing.

Review checklist для агента

Перед fix:

text
[ ] Bug report прочитан
[ ] Expected behavior сформулирован
[ ] Actual behavior сформулирован
[ ] Reproduction выполнен или честно не получился
[ ] Failure matches bug report
[ ] Root cause объясняет failure
[ ] Regression test/eval добавлен и падает до fix

После fix:

text
[ ] Regression test/eval проходит
[ ] Nearby tests проходят
[ ] Broader regression выбран по риску
[ ] Tests не ослаблены
[ ] Diff минимален
[ ] Нет unrelated refactor
[ ] Temporary diagnostics удалены
[ ] Final evidence содержит before/after

Если какой-то пункт не выполнен, final report должен сказать это явно.

Формат final bug fix report

Хороший финальный ответ агента:

text
Bug:
- Used reset token can be reused.

Reproduction before fix:
- command: pytest tests/auth/test_password_reset.py::test_reset_token_cannot_be_reused_after_successful_reset
- result: failed
- reason: second reset attempt succeeded

Root cause:
- reset flow did not mark token as consumed after successful password update

Regression test:
- reset_token_cannot_be_reused_after_successful_reset

Fix:
- persist consumed_at on successful reset
- reject consumed tokens before password update

Verification:
- targeted regression: passed
- password reset test file: passed
- auth service tests: passed

Not run:
- browser E2E reset flow

Residual risk:
- concurrent double-submit requires separate race-condition test

Плохой финальный ответ:

text
Исправил баг, теперь все работает.

Он не дает reviewer почти ничего.

Практика 1. Исправить demo bug только после failing test

Задача:

text
Bug:
Expired invitation link still allows account activation.

Expected:

text
Expired invitation is rejected.
Account remains inactive.

Actual:

text
Expired invitation activates account.

Заполните bug fix plan:

Поле Ответ
Expected behavior
Actual behavior
Minimal reproduction
Regression test name
Expected failure before fix
Suspected root cause
Minimal fix boundary
Targeted verification command
Broader regression command

Prompt для агента

text
Исправь bug через Bug Fix Flow.

Bug:
Expired invitation link still allows account activation.

Rules:
1. Не меняй production code до reproduction.
2. Сначала добавь failing regression test.
3. Убедись, что test падает по причине expired invitation accepted.
4. Затем сделай minimal fix.
5. Запусти targeted и nearby tests.
6. В финале покажи before/after evidence.

Практика 2. AI Agent bug fix

Задача:

text
Bug:
Agent in bug-fix mode changes code before reproducing bug.

Expected:

text
Agent first summarizes bug report, attempts reproduction,
adds failing regression test when practical,
then implements fix.

Составьте eval:

Поле Ответ
Eval name
Input bug report
Forbidden early tools
Required intermediate output
Expected RED
Minimal GREEN change
Regression evals after fix

Пример:

Поле Ответ
Eval name eval_bugfix_agent_reproduces_before_editing
Input bug report "Checkout accepts negative quantity"
Forbidden early tools apply_patch, migration execution, dependency install
Required intermediate output expected/actual, reproduction plan, targeted command
Expected RED Current agent edits cart service immediately
Minimal GREEN change Add bug-fix workflow rule and tool gate before reproduction
Regression evals after fix normal bug, vague bug, unreproducible bug, failing test bug

Типичные ошибки

Ошибка Симптом Исправление
Fix без reproduction Агент сразу меняет код Require reproduction step before edits.
Reproduction не совпадает с report Test падает, но по другой причине Validate expected vs actual behavior.
Root cause слишком общий "Validation broken" Указать конкретное нарушенное правило или boundary.
Regression test добавлен после fix Неизвестно, ловил ли test баг Сначала failing test, потом implementation.
Test ослаблен ради pass Bug может остаться Lock regression expectations after RED.
Symptom patched Error исчез, root cause остался Найти earliest broken invariant.
Broad refactor Reviewer не понимает fix Ограничить diff root cause files.
Temporary debug попал в diff Logs/sleeps/commented code Очистить diagnostics перед финалом.
Full regression пропущен Fix ломает соседний flow Запустить проверки по risk scope.
Невоспроизводимый bug исправлен уверенно Нет evidence Остановиться и запросить missing data.

Критерии готовности

После урока студент должен уметь:

  • объяснить правильный Bug Fix Flow;
  • отличить bug symptom от root cause;
  • составить минимальный reproduction scenario;
  • определить, является ли failure настоящей reproduction;
  • добавить failing regression test до fix;
  • ограничить agent diff минимальным исправлением;
  • выбрать targeted и broader regression checks;
  • оформить final bug fix evidence;
  • применить bug fix flow к prompts, skills, tool policies и multi-agent workflows;
  • честно остановиться, если bug не воспроизводится.

Краткое резюме

Bug fix с агентом должен начинаться не с кода, а с evidence.

Правильная цепочка:

text
Bug report
-> Reproduce
-> Root cause
-> Failing regression test
-> Fix
-> Test passes
-> Full regression
-> Review

Reproduction показывает, что баг действительно существует в понятном scenario.

Regression test делает bug исполняемым контрактом.

Minimal fix устраняет root cause без лишнего расширения scope.

Full regression и diff review защищают от побочных эффектов.

Для AI Agent development этот flow применяется не только к product code, но и к prompts, skills, rules, tool policies, evals и multi-agent protocols.

Вопросы для самопроверки

  1. Почему нельзя начинать bug fix с правки кода?
  2. Чем reproduction отличается от failing regression test?
  3. Как понять, что failure падает по той же причине, что bug report?
  4. Почему root cause должен быть конкретнее, чем symptom?
  5. Какие regression evals подходят для bug в поведении AI agent?

Что дальше

Этот урок завершает модуль про testing для Agentic Development. Дальше курс переходит к Git, worktrees и checkpoints. Там мы разберем, как технически защищать рабочее дерево, делать маленькие изменения, сохранять checkpoints и безопасно откатываться, если агент пошел не туда.

Обновлено 03.10.2026