"Fixed it, can't reproduce anymore" is not evidence — it is hope. The professional invariant: no fix attempt until a failing automated test reproduces the reported behavior.
Tier: Core · Workflow area: Debugging
Coding agents make this affordable for the first time: an agent can read the bug report, explore the code, and iterate until it has written a test that fails for the reported reason — and that test then becomes the fix's acceptance criterion and the permanent regression guard.
Skip only when a repro is genuinely impractical to automate (hardware faults, third-party outages) — then document the manual repro steps instead.
Brief the agent: repro only, no fixing. The separation is the whole method:
Bug report: "Customer 'annual' subscriptions that renew on the last day
of a month are charged twice when the renewal crosses a DST change in
the customer's timezone (report: renewal 2026-03-29, Europe/Berlin)."
Your ONLY job right now is a failing test. Do not fix anything.
1. Locate the renewal/billing rollover code and its existing tests.
2. Write a test in tests/billing/ reproducing this exact scenario:
fixed clock, timezone Europe/Berlin, renewal date 2026-03-29.
3. Run it. It must FAIL, and fail with the double-charge symptom
(two charge records), not with a setup error.
4. Show me the test, the failure output, and one sentence on why the
code produces it.
Audit the failure, not just the test. Read the failure output yourself. The test must fail for the reported reason. A test failing with fixture 'customer' not found reproduces nothing; a test asserting the wrong expectation "fails" uselessly. Ask: Explain why this failure output demonstrates the reported bug and not a test bug.
Harden the repro. Two quick checks: run it three times (must fail deterministically — flaky repro means the test still depends on real time or ordering), and confirm the assertion is on behavior a user described (charge count), not on internals that a refactor would break.
Now — and only now — fix. Same session or new one:
The failing test tests/billing/test_dst_renewal.py is the contract.
Fix the underlying bug. Constraints: the new test must pass, the whole
billing suite must stay green, and the fix must handle the general case
(any DST transition, any tz), not special-case 2026-03-29.
Cross-check with a sibling case. Ask for one more test at an adjacent boundary (southern-hemisphere DST, non-DST timezone control case) to confirm the fix generalizes and the control still passes. Overfit fixes die here.
Ship test + fix together. The PR contains both; the description quotes the original failure output — reviewers can see the bug existed and is gone.
The failing test converts a bug report into an executable specification — agents fix executable specifications far more reliably than prose complaints.
git stash the fix, run the test, watch it fail again — proves the test still guards the behavior.2026-03-29 is an alarm bell).The workflow runs entirely inside the repo, so with a client-sanctioned agent it transfers unchanged. Chat-only sanction: paste the billing function and existing test shapes (sanitized — fake customer IDs, no real amounts if contractually sensitive) and have the model draft the test for you to run locally. Local model route: mid-size coder models draft serviceable unit tests when you paste the target function plus one exemplar test; the run-audit-harden loop (steps 2-3) is yours regardless of which model drafted. Bug reports themselves often contain customer data — sanitize before pasting anywhere hosted.