İçeriğe atla

Bu Kodun Sahibi Kim: Hesap Verebilirlik ve Suçlama

Legacy kodu kimin yazdığını sormayı bırakın. Sorumluluğu, hesap verebilirliği ve suçlamayı ayırın; miras kodu sahipsiz bırakmak yerine sahiplendirin.

Ayhan Sipahi Ayhan Sipahi

“Bunu her kim yazdıysa aptalın tekiymiş” cümlesi yazılımda en sık kurulan, ama en işe yaramaz cümlelerden biridir. Analiz gibi görünür; oysa önemi olmayan bir soruyu yanıtlar. Bir dosyayı açıp tek bir satırı değiştirdiğiniz an, orijinal kodu kimin yazdığından bağımsız olarak, o kodun canlıdaki davranışının sahibi olursunuz. Yazarlık geçmiştir. Sahiplik ise şimdiki zamandır. Çoğu geliştirme ekibi için kalıcı yanıt şudur: makine tarafından okunabilir bir kayıt (bir CODEOWNERS dosyası ve bir servis kataloğu) ile desteklenen, gerçek bir on-call rotasyonuna sahip ekip düzeyinde servis sahipliği. Bunu işler kılan ise ekiplerin yanlışlıkla eş anlamlı sandığı üç kelimedir: sorumluluk (responsibility), hesap verebilirlik (accountability) ve suçlama (blame).

Bu karışıklık kendini sahipsiz kalmış legacy kod, net sahibi olmayan on-call rotasyonları ve bir düzeltme yerine bir isimle biten incelemeler olarak gösterir. Üç kelimeyi ayrı tutmak, miras alınan kodun sahiplenilmesini mümkün kılar: işletilen, izlenen ve düzeltilen kod. Olay incelemesinin kendisi ayrı bir konu; incelemenin içinde ne yapılacağını suçsuz postmortem modeli anlatır.

Ekiplerin Eş Anlamlı Sandığı Üç Kelime#

Çoğu sahiplik tartışması aslında bir kelime tartışmasıdır. Ekipler üç farklı fikri tek kelimeye sıkıştırır, sonra da neden kimsenin hiçbir şeyin hesabını vermediğine şaşırır. Onları ayrı tutun, kafa karışıklığının büyük kısmı ortadan kalkar.

KelimeYanıtladığı soruKaç kişiNe zaman geçerli
SorumlulukBugün işi kim yapıyor ve kodu kim işletiyor?Paylaşılabilirİş sürerken aktiftir
Hesap verebilirlikSonucun hesabını kim verir?Tam olarak birSonuçlar bilindikten sonra netleşir
SuçlamaAhlaki kusur kimde?Nadiren işe yararYalnızca gerçek ihmal veya kötü niyet

Bu ayrım doğrudan RACI’den, yani sorumluluk atama matrisinden gelir. Kanonik kuralı şudur: bir görevin birden çok Sorumlu (Responsible) kişisi olabilir, ama tam olarak bir Hesap Veren (Accountable) kişisi olur; sorumluluk göreve dönüktür ve paylaşılabilir, hesap verebilirlik sonuca dönüktür ve tekildir. Suçlama tamamen üçüncü bir şeydir. O bir ahlaki kusurdur ve sağlıklı organizasyonların gerçek ihmal dışında neredeyse her şey için emekliye ayırdığı bir kategoriye aittir. Hesap verebilirliği suçlamayla karıştırmak, çözülmesi gereken temel hatadır.

Konuyu kod ve servislerle sınırlı tutun. Bir kararın hesabını kimin verdiği farklı bir sorudur ve rol beklentileri ile ekip performansı yazısında ele alınır. Burada konu her zaman çalışan bir servis ve onu kimin işlettiğidir.

Yazarı Suçlamak Neden Titizlik Gibi Görünür#

Önceki geliştiriciyi suçlamak titizlik gibi görünür; çünkü temiz bir anlatı ve hızlı bir kapanış üretir. Aynı zamanda kodun neden o hâle geldiği konusunda yanlıştır ve bu yanlışın bedeli ağırdır.

Kendimi bunu yaparken yakaladım. Tanımadığım bir modülü açtığımda, bunu her kim yazdıysa framework’ü anlamamış diye söylendim. Sonra gözden kaçırdığım kısıtı açıklayan commit’i buldum: yalnızca tam olarak o biçimdeki istekleri kabul eden bir tedarikçi API’si. Kod dikkatsiz değildi. Artık göremediğim bir duruma verilmiş makul bir yanıttı.

Bu refleksin bir adı var. Ross’un 1977 tarihli çalışmasında tanımlanan temel atıf hatası (fundamental attribution error), başkalarının davranışını karakterleriyle, kendi davranışımızı ise koşullarımızla açıklama alışkanlığımızdır. Kod okumaya uygulandığında, önceki geliştiricinin “kötü” kodu genellikle bir teslim tarihine, bir veri biçimine ya da o günün bir aracına verilmiş makul bir yanıttı; sizin artık göremediğiniz bir yanıt. Geriye dönük bakış hatayı bariz gösterir; oysa orijinal kısıtlar altında bariz değildi.

Chesterton’ın Çiti (Chesterton’s Fence) bu refleksi durduran disiplindir. Bir çiti yıkmadan önce neden dikildiğini öğrenin. Onun bir işe yaramadığını söyleyen reformcuya şu yanıt verilmelidir: bir işe yaradığını görmüyorsan, önce git öğren, ancak ondan sonra onu kaldırmana izin verebilirim. Kodda “çit” o tuhaf koşul, o retry, o anlamsız görünen bekleme çağrısıdır. Silmeden önce kısıtı anlayın.

Miras alınan kodu devralmayı ve yeniden işlemeyi güvenli kılan şey, Weinberg’in egosuz programlama (egoless programming) fikridir: biz kodumuz değiliz. Kodu ekibin sahip olduğu bir nesne olarak görün. Kod kişisel bir şey olmaktan çıkıp paylaşılan bir nesne olduğunda, onu eleştirmek ve yeniden işlemek bir saldırı olmaktan çıkar ve bakıma dönüşür.

You Build It, You Run It#

Sahiplik bir wiki’deki etiket değildir. Bir servisi işlettiğinizde, izlediğinizde, düzelttiğinizde ve geliştirdiğinizde ona sahip olursunuz. Werner Vogels bu işleyiş modelini 2006 tarihli bir söyleşide “you build it, you run it” (sen inşa edersin, sen işletirsin) olarak tanımladı: geliştiricilere yazılımlarının işletimiyle ve müşteriyle günlük temas sağlamak, geri bildirim döngüsü doğrudan olduğu için kaliteyi artırdı.

Miras alınan bir kod parçası bozulduğunda, üç soru sırayla işler. Yalnızca ilk ikisinin işe yarar yanıtı vardır.

Sahip yok

Sahip ekip bulundu

Hayır

Evet

Miras alınan veya bozulan kod

Bugün kim işletiyor?

Sahip yok: asıl bug servisin sahipsizliğidir

Önce bir sahip ekip ata

Sonucun hesabını kim verir?

Tek bir hesap veren ekip, yazar değil

Gerçekten kusurlu biri var mı?

Neredeyse her zaman hayır: sistemi düzelt, suçsuz incelemeye yönlendir

Nadir: ihmal veya kötü niyet, Just Culture yolu

Kim işletiyor sorusuyla başlayın. Sahip ekibi CODEOWNERS veya katalog üzerinden bulun. Sahip yoksa asıl bug servisin sahipsizliğidir; koda dokunmadan önce bir sahip atayın. Sonra sonucun hesabını kimin verdiğini sorun: kodu kim yazmış olursa olsun, hesabı sahip ekip verir. Yalnızca en sonda gerçekten kusurlu biri olup olmadığını sorun; yanıt neredeyse her zaman hayırdır. Kusur, Just Culture yoluna yönlendirdiğiniz nadir bir istisnadır. Pratikte sahip bir ilk müdahale eden kişidir, bir sanık değil.

Sahipliği Makine Tarafından Okunabilir Kılmak#

Bir wiki’de ilan edilen sahiplik, sınandığı an buharlaşır. Hayatta kalan sahiplik makine tarafından okunabilir ve pager’a bağlıdır. Yükün çoğunu iki artefakt taşır.

Bir CODEOWNERS dosyası, yol desenlerini sahip ekiplere eşler. Bir pull request bir yola dokunduğunda, GitHub eşleşen ekipten otomatik olarak inceleme ister ve yöneticiler birleştirmeden önce kod sahibinin onayını zorunlu kılabilir. Eşleşen son desen kazanır ve sahiplerin depo üzerinde yazma erişimi olması gerekir.

# .github/CODEOWNERS
# Her satır bir yol desenini bir veya daha fazla sahip ekibe eşler.
# Eşleşen son desen öncelik kazanır.

*                     @acme/platform
/services/billing/    @acme/payments
/services/checkout/   @acme/checkout
/infra/               @acme/platform @acme/sre
*.tf                  @acme/sre

İkinci artefakt bir servis kataloğudur. Backstage’de Component, API ve System gibi çekirdek katalog varlıkları, bir Group veya User’a karşılık gelen bir spec.owner bildirmek zorundadır; bu da her servisin sahibi için tek bir doğruluk kaynağı verir.

# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: billing-service
  description: Charges and invoices for customer accounts
  annotations:
    github.com/project-slug: acme/billing-service
    pagerduty.com/service-id: PXXXXXX
spec:
  type: service
  lifecycle: production
  owner: team-payments
  system: billing

Bir uyarı var ki buradaki her alandan daha önemli. Kapatılmış bir ekibi işaret eden sahip, hiç sahip olmamaktan daha kötüdür; çünkü kayıt yanıtlanmış gibi görünür ama arkasında kimse yoktur. Kayıt, girdiler eskidiğinde bunun görünür olması için gerçek bir organizasyon şeması kaynağına ihtiyaç duyar. İşe yarar yerel bir sinyal, adlı ve canlı bir sahibi olan servislerin oranıdır; hedef bu oranı tama, sahipsiz servis sayısını sıfıra yaklaştırmaktır. Bunu kendi ürettiğiniz bir gösterge olarak değerlendirin; arkasında kaynak gösterilebilir bir kıyas yok.

Burada gerçek bir trade-off var. Katı kod sahipliği, kolektif kod sahipliğine karşı çalışan inceleme darboğazları ve “benim kodum değil” siloları yaratabilir. Çözüm, sahipliği ekip düzeyinde tanımlamaktır. Adlı bir hesap veren ekip, hesap verebilirliği tekil tutarken kod kolektif olarak düzenlenebilir kalır; ekip düzeyinde sahiplik, bireysel kapı bekçiliğiyle aynı şey değildir.

Ayrılıklar ve Devir Ritüeli#

Sahip bir ekip, sahip bir kişinin atlatamadığı şeyi atlatır: bir ayrılığı. Bireysel sahiplik bir kişilik bir bus factor yaratır ve bilgi kişiyle birlikte gider. “Software Engineering at Google”, bir ekibin başarısını tek bir kişiye atfeden Deha Miti’ni (Genius Myth) bir tuzak olarak adlandırır ve kalıcı sahipliği birincil ve ikincil bir sahip ile dokümantasyona bağlar. Sahiplik bir ekip özelliğidir; yalnız kahraman bir risktir.

Evet

Hayır

Servisin bir sahip ekibi var

Sahip ayrılır veya ekip yeniden yapılanır

Devir ritüeli yapıldı mı?

Yeni sahip ekip: runbook, dashboardlar, on-call, erişim, bilinen sorunlar devredildi

Sahipsiz servis: sahip yok, on-call yok

Sonraki olayda ilk müdahale eden yok

Bir kişi veya ekip ayrıldığında sahiplik bir ritüelle devredilir. Ritüel runbook’u, dashboard’ları, erişimi, bilinen sorunları ve pager’ı teslim eder. Bunu atlarsanız servis sahipsiz kalır: sonraki olayda ilk müdahale eden kimse olmaz ve konuşma yeniden “bunu kim yazdı?” sorusuna döner. Yüksek bir bus factor devri en baştan mümkün kılan şeydir. Operasyonel sahipliği Definition of Done’a katın; böylece bir özellik, adlı bir ekip onu işletmeyi sahiplenmeden bitmiş sayılmaz.

Liderlerin Sorduğu Soru#

Bir liderin herkesin önünde sorduğu soru, tüm ekibe bir sonraki adımda ne yapacağını öğretir. Açıkça sorulan “bunu kim bozdu?” insanlara bir sonraki sorunu gizlemeyi öğretir ki bu, liderin istediği hesap verebilirliğin tam tersidir. Onu farklı bir soruyla değiştirin: hangi servis, hangi sahip ve neyi değiştiriyoruz?

Miras alınan kodda bir bug ortaya çıkar

Sağlıksız soru: bunu kim yazdı?

Sağlıklı soru: bunun sahibi kim, neyi değiştiriyoruz?

Yazar suçlanır, kimse kodu sahiplenmez

Kod sahipsiz kalır

Bug tekrar eder, hala sahibi yok

Sahip ekip ilk müdahale eden olarak yanıt verir

Sistem düzeltmesi çıkar

Sahiplik pekişir, kayıt güncel kalır

Amy Edmondson’ın psikolojik güvenliği (psychological safety) sağlıklı döngünün ön koşuludur. Soruları, endişeleri ve hataları açıkça dile getirmenin güvenli olduğuna dair ortak inançtır. Cezalandırılma korkusu olmadan açık sözlülük demektir; kibarlıkla ilgisi azdır. O olmadan dürüst sahiplik yerine gizlenmiş sorunlar elde edersiniz. Liderler bunu suçlamayı üstlenerek ve övgüyü dağıtarak pekiştirir ki bu da Extreme Ownership’in gerçekten işe yarayan yarısıdır.

Varsayılandan Ne Zaman Sapmalı#

Ekip düzeyinde servis sahipliği varsayılandır; ama iki durum farklı bir kurulumu haklı çıkarır ve popüler bir çerçevelemeye de bir sınır çizmek gerekir.

Küçük ekipler veya düşük kritiklikteki kod için bireysel sahiplik kabul edilebilir. Bus-factor riski gerçektir ama kod kritik yolda değilken ve ekip, herkesin tüm kodu okuyabileceği kadar küçükken tolere edilebilir. Kaçınılması gereken biçim, gayri resmi “X’e Slack’ten sor” sahipliğidir; çünkü her yeniden yapılanmada kaybolur ve arkasında hiçbir artefakt bırakmaz.

Extreme Ownership, yani kötü ekip yoktur yalnızca kötü lider vardır diyen liderlik fikri, aynı anda hem yararlı hem tehlikelidir. Gücü, bir liderin suçlamayı üstlenmesi ve sonucu sahiplenmesidir. Başarısızlık biçimi ise sistemik bir başarısızlığı yeniden tek bir kişinin üstüne yıkmasıdır; suçsuz kültürün düzeltmek için var olduğu şey tam da budur. Sentez dar ve önemlidir: lider sonucu ve onarımı sahiplenir; bir sistem boşluğunu kişisel suça çevirmez.

“You build it, you run it” kaliteyi artırır, ama tam ve farklılaşmamış sahiplik bir tükenmişlik vergisine dönüşebilir. Eleştirmenler, her ekip kendi her şeyini işlettiğinde modeli on-call yüküne ve bilişsel yük yayılmasına bağlar. Platform mühendisliği karşı görüşü ilkeyi korur ve farklılaşmamış yükü, bazen golden path (altın yol) denen döşenmiş yollar üzerinden bir platform ekibine taşır. Uyarı dürüsttür: kötü kurulmuş bir platform yükü ortadan kaldırmaz, yalnızca yerini değiştirir. “Ona sen sahipsin” için döşenmiş bir yol gerekir, yoksa sahiplik insanların sessizce ödemeyi reddettiği bir vergiye dönüşür.

Yaygın Tuzaklar#

Birkaç hata biçimi tekrar tekrar ortaya çıkar; her birinin somut bir çözümü var.

  • Miras alınan kodu anlamadan yeniden yazmak. Çiti kaldırmadan önce neden orada olduğunu öğrenin.
  • Sahipliği arkasında hiçbir şey olmayan bir wiki’de ilan etmek. Sahiplik CODEOWNERS’ta veya katalogda yaşamalı ve bir pager taşımalıdır.
  • Bir sonuç için beş kişinin “hesap veren” olması. Tam olarak bir hesap veren ekip; geri kalanı sorumludur.
  • Hesap verebilirliği suçlamayla eş anlamlı saymak. Hesap verebilirlik sonucun hesabını verir ve düzeltmeyi yürütür; suçlama ahlaki kusur atar ve nadiren yardımcı olur.
  • Ayrılışta servislerin sahipsiz kalmasına izin vermek. Bir sahiplik-devir ritüelini offboarding’in ve her yeniden yapılanmanın parçası yapın.
  • Liderlerden açıkça “bunu kim bozdu?” sorusu. Sağlıklı soruyu kendiniz sorarak örnek olun, suçlamayı üstlenin ve övgüyü dağıtın.

Sonuç#

Varsayılan neredeyse her şey için geçerlidir; istisnalar dardır. Bireysel sahipliğe yalnızca küçük, düşük kritiklikteki kodda başvurun ve “you build it, you run it” ilkesini döşenmiş bir yolla eşleştirin ki sahiplik tükenmişliğe dönüşmesin.

Tek bir şey yapacaksanız, en çok miras aldığınız servisi açın ve bir kayıtta adlı, canlı bir sahibi olup olmadığını kontrol edin. Yoksa asıl bug budur ve bu, kodu her kim yazdıysa onun isminden çok daha işe yarar bir bulgudur.

Kaynaklar#

İlgili yazılar

Suçsuz Postmortem: Bir Model ve Kopyala-Yapıştır Şablon

Suçlu aramak yerine sistemi düzelten bir suçsuz postmortem modeli, kopyalanabilir bir şablon ve bireysel sorumluluğun hâlâ geçerli olduğu sınır.

engineering-culture · incident-response · psychological-safety +4

Takım Çatışması Çözümü: Yüksek Performansa Giden Yol Haritası

Yazılım takımlarında çatışmayı erken fark etme, yönetme ve çözme rehberi: pratik framework'ler, erken uyarı metrikleri ve sürtüşmeyi performansa çeviren kalıplar.

leadership · team-management · best-practices +4

Mühendislik Ekibi Dokümantasyonu: Çalışma Anlaşmaları, Definition of Done ve Nöbet Belgeleri

Olgun bir mühendislik ekibinin sahiplendiği belgelere bir rehber: onboarding, takım anlaşmaları, Definition of Done, nöbet, bilgi aktarımı ve her birini iyi yapan şey.

engineering-culture · hiring · documentation +4

Scrum, Kanban ve Scrumban: Yapay Zeka Destekli Ekipler

Yapay zeka uygulamanın çoğunu üstlendikçe çerçevenin adı dört geri besleme döngüsünden daha az önem taşır. Akış, tempo, WIP ve inceleme için bir karar merceği.

leadership · agile · team-management +3

Kültürel Körlüğün Gizli Maliyeti: Global Engineering Takımları Nasıl Başarısız Oluyor

Kültürel yanlış anlaşılmalar global yazılım takımlarını sessizce başarısızlığa sürükler; geri bildirim, toplantı ve eskalasyonu kültüre uyarlamanın pratik çerçeveleri.

leadership · team-management · remote-work +2