İçeriğe geç
Muhammet Şafak
en
Günlük 4 dk okuma

Aynı hata, başka başlık: bir LLM bulgusuna kimlik vermek

CommitBrief'te bir bulgunun 'aynısı' sayılması başlıktan kural kimliğine taşındı; baseline, policy ve PR thread'leri bu kararın üstüne kuruldu.

Kısaca

CommitBrief ilk baseline'ında bulguyu dosya, severity ve başlıkla tanıyordu; model başlığı değiştirince bulgu geri geliyordu. v1.19.0'da kimlik dosya, kapalı taksonomiden bir kural kimliği ve symbol oldu. Baseline, policy, SARIF ve PR yorum senkronu aynı kimliğe yaslanıyor.

Koyu zeminde indigo tüylü Tan el fenerinin mor huzmesini masadaki üç kâğıda tutuyor; kâğıtlarda dalgalı, zikzaklı ve noktalı farklı çizgi desenleri var, üçünün köşesinde de aynı mor halkalı mühür parlıyor

Baseline’a aldığım bir bulgu, hata aynı kaldığı hâlde geri geliyordu. Değişen tek şey modelin bulguya verdiği başlıktı.

CommitBrief’te bir bulgunun “aynısı” olmanın neye bağlı olduğunu uzun süre sormadım. Bu yazı, o sorunun cevabını bulgunun kimliği olarak yazılı hâle getirmenin ve bu tek kararın arkasından gelen özelliklerin hikâyesi. Aracı neden yazdığımı ve PR akışına nasıl taşıdığımı önceki yazılarda anlatmıştım.

v1: kimlik başlıktı

v1.8.0’da (2026-06-20) baseline geldi. Mevcut bir depoda bugünkü bulguları bir kez kabul ediyorsunuz, sonraki koşularda yalnız yeni olanları görüyorsunuz. Bir bulguyu tanımak için şu parmak izini kullanıyordum:

sha256(File + Severity + normalize(Title))

Satır kaymasına dayanıklıydı: bulgu dosyada yukarı aşağı gitse de baseline’da kalıyordu. Ama başlığa bağlıydı, ve başlığı yazan ben değil, modeldi. Model aynı hatayı bir sonraki koşuda başka bir başlıkla yazınca, baseline’a aldığım bulgu “yeni” sayılıp geri geliyordu. Modelin severity’yi yeniden derecelendirmesi de aynı sonucu veriyordu.

Aynı tavanı v1.10.0’daki policy gate’de de görmüştüm. Changelog’a o gün şunu yazmışım: “Rule-id-scoped allow/deny lists are deferred (findings carry no stable rule id).” Kural bazlı izin ve yasak listesi yapamıyordum, çünkü bulgunun kararlı bir kural kimliği yoktu.

“Aynı”yı tanımlamak

v1.19.0’da (2026-10-18) kimliği başlıktan çıkarıp iki parçaya böldüm.

Birincisi kural kimliği (rule_id). 30 kimlikli kapalı bir taksonomi: sec.injection, correctness.error-handling, test.flaky ve general.other gibi. Model bunu kendisi seçiyor; OpenAI, Anthropic ve Gemini şemalarında rule_id zorunlu ve değerleri taksonomiyle sınırlı. Boş ya da bilinmeyen bir değer gelirse tekrar denenmiyor, doğrudan general.other’a çekiliyor. Etiket konusunda gevşek olan bir model, geçerli bir review’ı bozmasın istedim. Deterministik üreticiler kimliği kendileri veriyor: flaky süzgeci test.flaky, leaks ise sec.hardcoded-secret yazıyor.

İkincisi symbol. Modelden gelmiyor, diff’ten yerelde türetiliyor: bulgunun satırını içeren hunk’ta o satıra kadar, git’in varsayılan funcname kuralına uyan son satır, yani ilk karakteri harf, _ ya da $ olan satır. Parantez içleri ()’ye indirildiği için parametre listesi değişince symbol değişmiyor. Bu yüzden kimlik şu oldu:

fingerprint = sha256(file, rule_id, symbol)

Başlık, severity ve satır numarası formülde yok. Kimlik her koşuda yerelde hesaplanıyor, cache’e yazılmıyor; cache’ten gelen bulgu için de güncel diff’ten yeniden hesaplanıyor. Formül bir gün değişirse eski kimlikler cache’te kalıp yanlış eşleşmesin diye böyle yaptım.

Aynı kimlikle gelenler

Kimlik bir kere kararlı olunca, bekleyen özellikler tek tek yerine oturdu.

  • Baseline v2 artık kimlikleri saklıyor. Başlığı değişen bulgu baseline’dan düşmüyor.
  • Policy rules.deny ve rules.allow kazandı. deny listesindeki bir kuraldan tek bir bulgu kapıyı kapatıyor; allow listesindekiler eşiklerden ve toplamdan muaf tutuluyor. Girdi, taksonomideki bir kimlik ya da <category>.*.
  • Satır içi işaretler kural kapsamı aldı: commitbrief-ignore[sec.injection]: gerekçe yalnız o kuralın bulgusunu susturuyor.
  • SARIF çıktısı kimliği partialFingerprints["commitbrief/v1"] altında taşıyor. SARIF’in başarısız olduğunda neden dosya yazmadığı ayrı bir konu; burada yalnız anıyorum.

Zincirin en görünür halkası v1.20.0’daki remote pr değişikliği. Eskiden her koşu yorumları yeniden atıyordu. Şimdi her satır içi yorumun sonunda gizli bir marker var:

<!-- commitbrief:fp=<fingerprint> v=1 -->

Bir sonraki koşu kendi thread’lerini bu marker’dan tanıyor. Durmaya devam eden bulguya dokunmuyor (metin değiştiyse yorumu yerinde düzenliyor), yeni bulguyu bir kez yazıyor, kaybolan bulgunun thread’ini kapatıyor, geri dönen bulgunun thread’ini yeniden açıyor. Bir insanın çözdüğü ya da yeniden açtığı thread’lere hiç dokunmuyor. Aynı kimliğin tekrarları tek thread’de Also at: altında toplanıyor. Thread’i kapatma yetkisi yoksa yanıt olarak No longer present as of <sha> yazıyor.

Aynı sürümde --since-last-review da geldi: her tam PR review’ının sonuna <!-- commitbrief:reviewed=<head sha> --> marker’ı ekleniyor, bayrakla yalnız yeni commit aralığı inceleniyor. Force-push, merge commit ya da aralık güvenle belirlenemezse tam review’a dönüyor. v1.21.0’dan beri remote pr satır içi susturmaya da uyuyor; baseline remote pr’a uygulanmıyor.

Bedeli

  • v1’den v2’ye geçiş kayıplı. Başlık hash’lerinden kural kimliği ve symbol geri çıkarılamıyor; --update-baseline ile yeniden almak gerekiyor.
  • v1.20 öncesi yorumlarda marker yok. Önceden review edilmiş bir PR’da ilk v1.20 koşusu bulguları bir kez daha yazıyor.
  • Taksonomi bloğu prompt’a changelog’daki tahminle yaklaşık 690 token ekliyor. System prompt cache anahtarının parçası olduğu için mevcut cache girdileri yükseltmeden sonra bir kez ıskalıyor.

Sınırlar — yine dürüst liste

  • Kimlik hâlâ kısmen modele bağlı. rule_id’yi model seçiyor ve bulgunun satırını o veriyor; satır da hangi symbol’e düşeceğini belirliyor. Aynı hata iki koşuda farklı kuralla gelirse kimlik değişir. Bu kararlılığın ne kadar tuttuğuna dair burada vereceğim bir ölçümüm yok; modelleri review kalitesi ekseninde ölçtüğüm önceki yazı rule_id kararlılığını ölçmedi.
  • Kapalı taksonomi kaba. general.other’a düşen bulgular ayırt edilemiyor; baseline’daki kapsamı da geniş.
  • Aynı kuralın aynı symbol’deki iki bulgusu çakışır. Baseline’a alınan bir bulgu, aynı symbol’de aynı kuraldan gelecek bulguları da gizler.
  • Girintili satır symbol olmaz. Python sınıf metotlarında symbol sınıf satırına ya da boş değere düşebilir; kardeş metotlar aynı symbol’ü paylaşır.
  • Symbol, diff’in türüne bağlı. Tarama önce yeni taraftaki satırlara bakıyor, bulamazsa git’in eski koddan yazdığı hunk başlığına düşüyor. Aralıkta yeniden adlandırılan bir fonksiyon için --staged ile main..HEAD farklı symbol, dolayısıyla farklı kimlik verebilir. Baseline’ı aldığınız türden diff’le karşılaştırın. Dosya adı değişince de kimlik değişir.
  • CLI tabanlı sağlayıcılar düz metin ürettiği için rule_id ve fingerprint yok.

Denemek için

Kendi aracınızda ya da CommitBrief’te bir bulguyu baseline’a alıp bir sonraki koşuda geri gelip gelmediğine bakın. Geliyorsa, aracınızın “aynı bulgu”yu neye bağladığını yazılı hâle getirmek için iyi bir gün bugün.

Bu konudaki deneyler

Rust ve Tauri 2 ile yazılan açık kaynak bir masaüstü uygulaması toplantının sesini ve değişen ekran karelerini kaydedip özet ve aksiyon notu çıkarıyor.

Şu an ne yapıyor

Toplantının mikrofon ve sistem sesini ayrı kanallarda, ekranın yalnızca değişen karelerini kaydedip özet, karar, aksiyon maddesi ve açık soru içeren bir not çıkarıyor. Toplantı kaydını videoya çevirmeden nota dönüştürmek isteyen herkes kaynaktan derleyip deneyebilir.

Desktop Open-Source Rust Tauri 2 React +4 daha
Kasım 2026 — Devam ediyor

Claude Code, Codex CLI ve Gemini CLI loglarını yerelde okuyan bir masaüstü uygulaması, token kullanımını proje, model ve oturuma göre gösteriyor.

Şu an ne yapıyor

AI agent token kullanımını yerel loglardan toplayıp proje, model, oturum ve zaman bazında gösteriyor; tahmini maliyet ve abonelik limiti takibi sunuyor. Claude Code, Codex CLI veya Gemini CLI'ı yoğun kullanıp harcamasını görmek isteyen geliştirici kurabilir.

Open-Source Desktop Go Wails Svelte +2 daha
Kasım 2026 — Devam ediyor

Yorumlar

Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi