홈 / Skills / 개발 생산성 / Diagnosing Bugs 버그 진단
개발 생산성

Diagnosing Bugs 버그 진단

Matt PocockMITSkill 언어: 영어
라이선스 확인됨스크립트 포함
데모실행 기록 · claude-opus-5-5 · 2026년 10월
Customers report that invoices issued on a Friday get a due date that lands on a Saturday. Example: an invoice issued Friday 2026-10-02 with the default 10 business-day terms shows a due date of Saturday 2026-10-17. Finance says it should be Friday 2026-10-16. The code is in billing/due_dates.py and the tests run with `python3 -m pytest -q`. Debug this and fix it.
Skill: diagnosing-bugs
Bash: git ls-files && cat billing/due_dates.py && ls GLOSSARY.md 2>/dev/null; python3 -m pytest -q 2>&1 | tail -5
Bash: cat tests/test_due_dates.py; git log --format='%h %s' -- billing; python3 -c "…
Bash: python3 -c "…
Bash: cat >> tests/test_due_dates.py <<'EOF'…
Edit: billing/due_dates.py
Bash: python3 -m pytest -q 2>&1 | tail -2; python3 -c "…

I fixed it: an invoice issued Friday 2026-10-02 now gets a due date of Friday 2026-10-16, and all 4 tests pass.

Cause: invoice_due_date in billing/due_dates.py had an extra step, commented "Invoices issued late in the week reach customers after the weekend." It added one calendar day whenever the invoice was issued on a Friday, Saturday or Sunday (issued.weekday() >= 4). The business-day count by itself was already correct (2026-10-16). Adding one calendar day to that Friday moved it to Saturday.

How I confirmed it:

  • A one-line check of the reported invoice returned 2026-10-17 Saturday, matching the customer reports.
  • Running only the business-day count (add_business_days) gave 2026-10-16, so that part was fine.
  • I checked every issue weekday against terms of 1–30 days. 18 combinations gave a weekend due date, and every one was issued Fri/Sat/Sun, which are exactly the days the extra step applied to.

Fix: I removed that extra step, so invoice_due_date now just returns add_business_days(issued, terms_days). A Saturday or Sunday invoice is still handled sensibly, because the count already starts from Monday.

Regression tests, added to tests/test_due_dates.py. Both failed before the fix and pass now:

  • test_invoice_issued_on_friday_is_due_on_a_friday: the exact case Finance reported.
  • test_invoice_due_date_never_falls_on_a_weekend: checks every issue weekday with terms of 1–30 days.

For Finance to confirm: this removes a deliberate rule. Besides the weekend problem, it also moved some weekday due dates one day later (e.g. a Friday invoice with 3-day terms was due Thursday, and is now due Wednesday). Finance's expected date implies no grace day at all, so I removed it entirely. If they do want extra time for late-week invoices, it should be added as a business day instead (which would make the example due Monday 2026-10-19); that conflicts with the date they gave.

I haven't committed anything; the changes are in your working tree.

Code changes recorded in the trial sandbox (git diff):

diff --git a/billing/due_dates.py b/billing/due_dates.py
index 35d3932..1fd87e9 100644
--- a/billing/due_dates.py
+++ b/billing/due_dates.py
@@ -14,8 +14,4 @@ def add_business_days(start: date, days: int) -> date:
 
 def invoice_due_date(issued: date, terms_days: int = 10) -> date:
     """Due date for an invoice with `terms_days` business-day payment terms."""
-    due = add_business_days(issued, terms_days)
-    # Invoices issued late in the week reach customers after the weekend.
-    if issued.weekday() >= 4:
-        due += timedelta(days=1)
-    return due
+    return add_business_days(issued, terms_days)
diff --git a/tests/test_due_dates.py b/tests/test_due_dates.py
index 497750a..4d1cbde 100644
--- a/tests/test_due_dates.py
+++ b/tests/test_due_dates.py
@@ -1,4 +1,4 @@
-from datetime import date
+from datetime import date, timedelta
 
 from billing.due_dates import add_business_days, invoice_due_date
 
@@ -9,3 +9,14 @@ def test_add_business_days_skips_weekend():
 
 def test_invoice_issued_on_monday():
     assert invoice_due_date(date(2026, 9, 28)) == date(2026, 10, 12)
+
+
+def test_invoice_issued_on_friday_is_due_on_a_friday():
+    assert invoice_due_date(date(2026, 10, 2)) == date(2026, 10, 16)
+
+
+def test_invoice_due_date_never_falls_on_a_weekend():
+    for offset in range(7):
+        issued = date(2026, 9, 28) + timedelta(days=offset)
+        for terms in range(1, 31):
+            assert invoice_due_date(issued, terms).weekday() < 5, (issued, terms)

Real run recorded with claude-code / claude-opus-5-5. Run in a temporary directory containing a sample project, with Edit and Bash enabled. Tool-call lines show only the first line of each command. The last block is the git diff recorded when the trial ended. Both model outputs are unmodified.

하는 일

까다로운 버그와 성능 저하를 다루는 엄격한 절차입니다. 핵심 주장은 이렇습니다. 그 버그에 대한 분명한 성공/실패 신호만 있으면 원인 찾기는 기계적인 일이 되므로, 노력의 대부분을 먼저 그 신호를 만드는 데 써야 합니다.

작동 방식

  1. 피드백 루프: 이 버그에서 확실히 실패하고, 결과가 일정하며, 빠르고, 에이전트가 사람 없이 실행할 수 있는 명령 하나를 만듭니다. 이것이 생기기 전에는 원인을 추측하지 않습니다.
  2. 재현과 최소화: 사용자가 말한 증상이 재현되는지 확인하고, 남은 요소가 모두 필수가 될 때까지 입력을 줄입니다.
  3. 가설: 반증 가능한 가설을 순위를 매겨 3~5개 쓰고, 검증 전에 사용자에게 보여 줍니다.
  4. 계측: 한 번에 변수 하나만 바꾸고, 로그보다 디버거를 우선하며, 모든 디버그 로그에 고유한 접두어를 붙여 한 번의 검색으로 지울 수 있게 합니다.
  5. 수정: 알맞은 테스트 접점이 있으면 회귀 테스트를 먼저 쓰고 고칩니다.
  6. 정리: 처음의 루프를 다시 실행하고, 디버그 코드를 지우고, 확인된 원인을 커밋 메시지에 적습니다.

이럴 때 좋습니다

간헐적인 버그, "전에는 됐는데" 하는 회귀, 느려진 코드.

알아 둘 점

저장소에 GLOSSARY.md와 ADR이 있으면 먼저 읽습니다. 저희 테스트에서는 문제가 된 보정을 제거하고 테스트 두 개를 추가했습니다.

참고 및 위험

bash 템플릿 스크립트(hitl-loop.template.sh) 1개가 들어 있습니다. 안내문을 출력하고 Enter 입력이나 답변을 기다릴 뿐이며, 읽어 본 결과 네트워크 호출도 파일 쓰기도 없습니다. Skill 자체는 에이전트에게 명령 실행, 임시 디버그 로그 추가, 회귀 테스트 작성, 코드 수정을 시키므로 저장소가 바뀝니다. 보여 주는 내용에서는 비밀 값을 가리도록 지시합니다. 패키지에는 원본 저장소의 MIT 라이선스(LICENSE)와 agents/openai.yaml(Codex용 표시 이름)도 들어 있습니다.