Memperbaiki Bug yang Sama Dua Kali Adalah Kegagalan Proses
Setiap tim punya satu defek yang terus kembali. Kesalahan off-by-one dalam paginasi. Pengecekan null yang hilang di auth middleware. Race condition di checkout yang “diperbaiki” seseorang tiga sprint lalu.
Anda tidak menulis bug yang sama tiga kali. Anda menulis tiga bug berbeda dengan penyebab yang sama. Perbaikannya mengatasi gejala. Penyebabnya tetap tersembunyi.
Fagan inspection dirancang untuk menemukan defek sebelum mereka lolos. Kebanyakan tim berhenti di fase perbaikan. Penulis memperbaiki masalah yang tercatat, moderator memverifikasi perbaikannya, dan semua orang melanjutkan. Itu adalah kesalahan. Fase tindak lanjut adalah tempat analisis kausal seharusnya berada. Lewatkan, dan Anda menjadwalkan inspeksi berikutnya untuk jenis defek yang sama.
Apa Arti Analisis Kausal yang Sebenarnya
Analisis kausal bukanlah analisis akar masalah. Analisis akar masalah bertanya “baris kode mana yang gagal dan mengapa.” Analisis kausal bertanya “apa dari proses kami yang memungkinkan kategori defek ini ada.”
Akar masalah dari null pointer exception adalah “kita lupa memeriksa null.” Temuan analisis kausal adalah “checklist review kami tidak mencakup null safety, dan aturan linting kami memperbolehkan dereferensi yang tidak diperiksa.” Satu memperbaiki bug. Yang lain memperbaiki pabriknya.
Dalam Fagan inspection, analisis kausal terjadi setelah perbaikan. Moderator mengelompokkan defek berdasarkan kategori dan memimpin sesi singkat untuk mengidentifikasi penyebab tingkat proses. Outputnya bukan perubahan kode. Itu adalah perubahan proses: checklist yang diperbarui, aturan lint baru, kesenjangan pelatihan, atau kriteria masukan yang dimodifikasi.
Mekaniknya: Cara Menjalankannya
Mulailah dengan log inspeksi. Setiap defek seharusnya sudah memiliki empat bidang: lokasi, tingkat keparahan, jenis, dan deskripsi. Tambahkan kelima selama analisis kausal: penyebab proses.
Moderator mengelompokkan defek berdasarkan jenis. Jika tiga dari dua belas defek adalah kesalahan kondisi batas, itu adalah pola. Jika dua adalah kesalahan penyalahgunaan API dari module yang sama, itu juga pola. Pola adalah sinyal. Defek individual adalah noise.
Untuk setiap pola, ajukan tiga pertanyaan:
- Bisakah kita mencegah kategori ini sebelum inspeksi?
- Mengapa mekanisme pencegahan yang ada melewatkannya?
- Apa perubahan termurah yang akan mencegah kategori ini lain kali?
Pertanyaan ketiga adalah di mana kebanyakan tim salah. Mereka menyarankan menulis ulang arsitektur. Itu adalah angan-angan. Tujuannya adalah perubahan proses terkecil yang menghilangkan kategori tersebut.
Pola kondisi batas mungkin berarti menambahkan “pengecekan off-by-one dan batas” ke checklist review. Pola penyalahgunaan API mungkin berarti menambahkan aturan analisis statis. Pola penanganan kesalahan yang hilang mungkin berarti memperbarui definisi selesai untuk mewajibkan tes jalur kesalahan.
Pelacak Analisis Kausal yang Berfungsi
Berikut adalah skrip Python yang mengambil log inspeksi, mengelompokkan defek berdasarkan jenis, dan meminta penyebab tingkat proses.
#!/usr/bin/env python3
"""
Run causal analysis on a Fagan inspection log.
Reads a JSON log, groups defects by type, and emits a causal analysis report.
"""
import json
import argparse
from collections import defaultdict
from dataclasses import dataclass, field
from typing import List, Dict
@dataclass
class Defect:
location: str
severity: str
defect_type: str
description: str
@dataclass
class CausalPattern:
defect_type: str
count: int
locations: List[str] = field(default_factory=list)
process_cause: str = ""
proposed_fix: str = ""
def load_log(path: str) -> List[Defect]:
with open(path, "r") as f:
raw = json.load(f)
return [Defect(**item) for item in raw]
def analyze_patterns(defects: List[Defect]) -> List[CausalPattern]:
groups: Dict[str, List[Defect]] = defaultdict(list)
for d in defects:
groups[d.defect_type].append(d)
patterns = []
for dtype, items in groups.items():
patterns.append(CausalPattern(
defect_type=dtype,
count=len(items),
locations=[d.location for d in items],
))
return sorted(patterns, key=lambda p: p.count, reverse=True)
def prompt_causal_input(patterns: List[CausalPattern]) -> List[CausalPattern]:
print("=== CAUSAL ANALYSIS SESSION ===")
print("For each pattern, identify the process cause and the cheapest fix.\n")
for p in patterns:
print(f"Pattern: {p.defect_type} ({p.count} occurrence(s))")
print(f"Locations: {', '.join(p.locations)}")
p.process_cause = input("Process cause: ").strip()
p.proposed_fix = input("Cheapest prevention fix: ").strip()
print()
return patterns
def emit_report(patterns: List[CausalPattern], output_path: str):
report = {
"summary": {
"total_patterns": len(patterns),
"total_defects": sum(p.count for p in patterns),
},
"patterns": [
{
"type": p.defect_type,
"count": p.count,
"locations": p.locations,
"process_cause": p.process_cause,
"proposed_fix": p.proposed_fix,
}
for p in patterns
],
}
with open(output_path, "w") as f:
json.dump(report, f, indent=2)
print(f"Report written to {output_path}")
def main():
parser = argparse.ArgumentParser(description="Causal analysis for Fagan inspections")
parser.add_argument("log", help="Path to inspection log JSON")
parser.add_argument("--output", default="causal_report.json", help="Output report path")
args = parser.parse_args()
defects = load_log(args.log)
patterns = analyze_patterns(defects)
if not patterns:
print("No defects found. Nothing to analyze.")
return
patterns = prompt_causal_input(patterns)
emit_report(patterns, args.output)
if __name__ == "__main__":
main()
Simpan log inspeksi sebagai inspection_log.json:
[
{"location": "src/auth.py:42", "severity": "major", "defect_type": "null-safety", "description": "Missing null check on user object"},
{"location": "src/orders.py:88", "severity": "minor", "defect_type": "boundary", "description": "Off-by-one in pagination limit"},
{"location": "src/auth.py:67", "severity": "major", "defect_type": "null-safety", "description": "Unchecked token decode result"}
]
Jalankan python causal_analysis.py inspection_log.json dan skrip akan memandu Anda mengidentifikasi penyebab proses. Laporan yang dihasilkannya menjadi masukan untuk siklus retrospektif atau peningkatan proses berikutnya.
Mengapa Kebanyakan Tim Melewatkan Ini
Analisis kausal menambah waktu pada proses yang sudah mahal. Fagan inspection standar untuk 250 baris memerlukan 8 hingga 12 jam-orang. Analisis kausal menambahkan 30 hingga 60 menit lagi.
Waktu ekstra itu terasa sia-sia ketika Anda punya backlog. Tetapi jika analisis kausal mencegah satu kejadian berulang dari kategori defek, ia membayar dirinya sendiri lain kali ketika kategori itu tidak muncul.
Masalah yang lebih sulit adalah kejujuran. Analisis kausal sering mengungkapkan bahwa defek ada karena tim melewatkan satu langkah. Kode tidak diuji sebelum inspeksi. Reviewer tidak menggunakan checklist. Checklist itu sendiri tidak lengkap.
Temuan ini bisa tidak nyaman. Tim yang memperlakukan analisis kausal sebagai penugasan kesalahan akan berhenti mendapatkan jawaban yang jujur. Moderator harus membingkainya sebagai peningkatan proses, bukan teater akuntabilitas.
Pertukaran Sebenarnya: Kecepatan vs. Pembelajaran
Anda punya dua pilihan setelah Fagan inspection. Menutup loop dengan memverifikasi perbaikan dan melanjutkan. Atau menutup loop dengan memverifikasi perbaikan dan belajar mengapa defek ada.
Pilihan pertama lebih cepat hari ini. Pilihan kedua lebih cepat dalam enam bulan ke depan.
Tim yang mendapatkan nilai terbesar dari Fagan inspection memperlakukan log inspeksi sebagai dataset. Pola defek adalah umpan balik. Mengabaikannya seperti menjalankan test suite dan tidak pernah melihat kegagalannya.
Tidak setiap kategori defek layak mendapat analisis kausal. Kesalahan ketik satu kali tidak memerlukan perubahan proses. Tetapi jika suatu kategori muncul dalam dua inspeksi berturut-turut, Anda memiliki masalah proses yang menyamar sebagai masalah kode.
Mulai dengan Module Berdampak Tertinggi
Anda tidak perlu menjalankan analisis kausal pada setiap inspeksi. Pilih module yang menghasilkan incident produksi paling banyak atau defek yang lolos paling banyak. Jalankan Fagan inspection lengkap, kumpulkan log, dan habiskan tiga puluh menit untuk analisis kausal.
Pertama kali Anda melakukan ini, perbaikan yang diusulkan akan jelas. Perbarui checklist. Tambahkan aturan lint. Tulis catatan tim singkat tentang pola tersebut. Pada inspeksi ketiga, Anda seharusnya melihat lebih sedikit defek dalam kategori yang sudah Anda analisis.
Jika jumlahnya tidak turun, perbaikan yang Anda usulkan terlalu samar. “Lebih berhati-hati” bukanlah perubahan proses. “Jalankan null safety linter di CI” adalah.
Lacak kategori defek per inspeksi dari waktu ke waktu. Jika analisis kausal melakukan pekerjaannya, kategori berulang akan menghilang. Jika tidak, Anda salah mengidentifikasi penyebab atau gagal mengimplementasikan perbaikannya.
FAQ
Apa itu analisis kausal dalam Fagan inspection?
Analisis kausal adalah langkah pasca-inspeksi di mana tim memeriksa defek yang ditemukan, mengelompokkannya berdasarkan kategori, dan mengidentifikasi penyebab tingkat proses. Tujuannya adalah mencegah kejadian berulang dengan mengubah checklist, alat, atau praktik, bukan hanya memperbaiki defek individual.
Bagaimana analisis kausal berbeda dari analisis akar masalah?
Analisis akar masalah mengidentifikasi alasan spesifik mengapa satu defek terjadi, seperti pengecekan null yang hilang. Analisis kausal mengidentifikasi mengapa proses memungkinkan seluruh kategori defek itu ditulis, seperti item checklist yang hilang atau aturan lint yang tidak ditegakkan.
Kapan harus menjalankan analisis kausal?
Jalankan setelah fase perbaikan dan tindak lanjut Fagan inspection, saat defek masih segar. Fokus pada pola yang muncul di beberapa defek atau telah muncul dalam inspeksi sebelumnya. Defek satu kali jarang membenarkan perubahan proses.
Bagaimana cara mengetahui apakah analisis kausal berfungsi?
Lacak kategori defek di berbagai inspeksi dari waktu ke waktu. Jika analisis kausal Anda efektif, frekuensi kategori berulang harus turun. Jika kategori yang sama terus muncul, perbaikan yang Anda usulkan salah atau tidak diimplementasikan.
Jalankan pada Log Inspeksi Berikutnya
Temukan log inspeksi terakhir Anda. Kelompokkan defek berdasarkan jenis. Untuk kategori teratas, tanyakan apa perubahan proses termurah untuk mencegahnya lain kali.
Tuliskan perubahan itu. Tetapkan pemiliknya. Verifikasi pada inspeksi berikutnya. Itulah analisis kausal. Yang lain hanyalah memperbaiki bug.