Kendi diff'imi bir tool'a soruyorum — CommitBrief'i niye yazdım
Self-review körlüğüyle yüzleştiğim bir öğleden sonra, terminalden çıkmadan kendi diff'imi denetleyen bir tool yazdım: CommitBrief. Niye yazdığım, nasıl çalıştığı ve hangi soruyu çözdüğü üzerine bir not.
Geçen ay bir öğleden sonra, açmak üzere olduğum bir PR’ı üçüncü kez yukarıdan aşağı okuyordum. Diff küçüktü — 80 satır eklenmiş, 14 silinmiş, dört dosya. Üçüncü okumada bile gözüm bir şeye takılmıyordu. PR’ı açtıktan iki saat sonra bir takım arkadaşı yorum bıraktı: “Burada bir hata wrap’i tekrar etmiş, %w zaten var, üstüne metin de eklemişsin — log’da iki kez ‘auth failed: auth failed:’ yazıyor şu an.” Üç kez okuduğum diff’te, gözümün dosyaya değdiği yerde olan bir hata.
Bu olayın küçük olmasının asıl gücü buydu. Dikkatsiz bir okuma değildi — dikkatli üç okumaydı. Kodu yazan kişi, kodu okuyamıyordu çünkü zaten okumuştu, zaten yazmıştı, zaten “biliyordu.”
Kendi kodumun en kötü okuyucusu benim
Self-review’un bir tuhaflığı var: yazdığın kodu okurken zihnin, yazdığın versiyonu değil, yazdığını sandığın versiyonu görüyor. Anchor bias diyorlar — “şu satırı şu sebeple yazdım” anısı satırın gerçek halini gizliyor. Bu yüzden bir geliştirici tek başına kendi diff’ini incelediğinde, ne kadar deneyimli olursa olsun, dış bir göze göre tutarlı biçimde daha az hata yakalıyor.
Pratik çözümler hep aynıydı:
- Beklemek. Bir gün bekle, yarın temiz gözle bak. Çoğu zaman bekleyemiyorum; deploy bugün.
- Bir takım arkadaşına sormak. En iyisi, ama her zaman müsait değil; üstelik küçük bir typo için birinin gününü bölmek doğru değil.
- IDE’deki AI asistanlarına sormak. Copilot review, Cursor review, JetBrains AI — hepsi çalışıyor, ama hepsinin ortak sorunu şu: dosya düzeyinde düşünüyorlar, değişiklik düzeyinde değil. Proje kurallarımı bilmiyorlar. IDE’den IDE’ye davranış farklı.
- ChatGPT’ye copy-paste. Çalışıyor, ama her seferinde diff’i panoya atmak, proje bağlamını tekrar yazmak, sonuçların hiçbiri cache’lenmiyor — friction yüksek.
Daha önce yazdığım gibi bu araçların değer ürettiği yer artık “kod yazmak” değil; yazdığın koda muhakeme uygulamak. İhtiyacım olan şey “AI yazsın” değil, “AI ikinci bir göz olsun” idi — ve mevcut hiçbir tool bunu terminalden çıkmadan, diff seviyesinde, benim kurallarımla yapmıyordu.
Bende CommitBrief yazdım.
Beş saniyede ne yapıyor
commitbrief yazdığım anda olan şey kısaca şu: staged diff’imi alıyor, üç katmanlı bir filtreden geçiriyor (built-in gürültü → .commitbriefignore → COMMITBRIEF.md’deki semantik kurallarım), seçtiğim LLM sağlayıcısına gönderiyor, dönen yanıtı sabit bir JSON şemasında işleyip terminale renkli kartlar olarak basıyor. Her bulgu için: severity (critical/high/medium/low/info), dosya, satır, başlık, açıklama, opsiyonel kod parçası.
$ commitbrief --staged
commitbrief v1.0.0 · provider: anthropic/claude-sonnet-4-6 · cache: miss
analyzing 3 files · 42 added · 11 removed
┌─ HIGH ─ internal/api/handler.go:201 ──────────────────────────┐
│ Wrapped error duplicated in message │
│ "%w" zaten var; prefix wrapped error'u tekrar ediyor, │
│ log'da "auth failed: auth failed: …" üretiyor. │
└───────────────────────────────────────────────────────────────┘
✓ Done in 4.2s · 1 finding · 8,421 tokens · Cost: $0.0319
Aynı diff’i tekrar çalıştırırsam dört saniye değil, 13 mikrosaniye sürüyor — yerel cache devreye giriyor, footer’da Saved: $0.0319 yazıyor. Diff değişmediği sürece bedava.
Çok özet bir tasarım listesi:
- Sağlayıcı-bağımsız. Anthropic, OpenAI, Gemini, Ollama (yerel). Üstüne
claude-clivegemini-cliüzerinden mevcut Claude Code / Gemini CLI aboneliğini de kullandırabiliyor — ekstra API key yok. - Yerel. Diff de inceleme çıktısı da makinede kalıyor. Tek dış istek seçtiğin sağlayıcıya.
- Proje-spesifik kurallar.
COMMITBRIEF.mdprojenin kök dizininde durur, system prompt olarak gider. “Bu projede magic number kabul etmiyoruz”, “context dışında error wrap’lemeyin”, “logger’ı doğrudan import etmeyin” — kuralları sen yazıyorsun. - Pre-send güvenlik. Diff içinde credential-şekilli substring varsa, sağlayıcıya gitmeden uyarıyor.
--allow-secretszorunlu bypass. - CI kapısı.
commitbrief --fail-on=criticalcritical bulgu varsa exit code 1 ile çıkıyor — pre-push hook ya da CI step olarak takılabiliyor.
Tek dosyalık Go binary; brew install CommitBrief/tap/commitbrief, scoop install commitbrief ya da go install github.com/CommitBrief/commitbrief/cmd/commitbrief@latest ile geliyor.
Asıl içgörü: doğru birim “dosya” değil, “değişiklik”
İlk haftalarda dosya seviyesinde düşünüyordum: “şu dosyayı AI’a okutayım.” Yanlış soyutlamaymış. Bir review’un gerçek birimi dosya değil, değişiklik. Bir reviewer üç yıldır o dosyaya bakmıyordu; bakacağı şey diff’in 12 satırı. AI’a da aynı şeyi göstermek gerek.
Bu küçük perspektif değişikliği işin yarısını çözüyor: token bütçesi düşüyor, gürültü düşüyor, severity ataması anlamlı hale geliyor — çünkü artık “bu fonksiyon iyi yazılmış mı” değil, “bu değişiklik soruna yol açıyor mu” sorusuna cevap aranıyor.
İkinci yarısı akış: aracın seninle aynı yerde — terminalde — olması, “ben bir tool’a soruyorum” eylemini bir saniyelik bir refleks haline getiriyor. Tarayıcı sekmesi açmak, copy-paste yapmak, sonra geri dönmek — bunların hepsi context switch maliyeti. Bir geliştiricinin gününde bu maliyet “kaç saniye sürdüğü” ile değil, “kaç kez sürdüğü” ile büyüyor.
Sınırları
CommitBrief mimari kararı sorgulamıyor — “bu özelliği yapmalı mıyım” diye sormuyor. Intent’i bilmiyor — “doğru özelliği mi yapıyorsun” diyemiyor. False positive üretebiliyor; benim akışımda bunlar genelde “info” seviyesinde ve görmezden gelmek kolay, ama yine de var.
Bu toolun yerini doğru koymak gerekiyor: lint’in yerine değil, lint + test’in üstüne bir katman. “İnsan reviewer benim PR’ımı görmeden önce, kendi gözümün üstüne bir göz” — orada faydalı, orada bitiyor.
Denemek için
- Site: commitbrief.com
- Kaynak: github.com/CommitBrief/commitbrief
- Portfolyo sayfası: /portfolyo/commitbrief
Süreci hangi sayılarla hızlandırdığı, üç ayda hangi bulgu paternlerinin tekrar ettiği, nereye kadar güvendiğim ve nerede dikkatli olduğum — bunları takip eden bir yazıda ayrıca anlatacağım. Şimdilik benim için kazanım net: üretim ucuzladıysa, üretileni denetlemek pahalı kalmamalı.