On developer, tek bir docs klasörü
Superpowers, becerileri spec'leri ve implementasyon planlarını markdown dosyaları olarak yazıp repoya commit eden bir Claude Code plugin'idir (286.000 GitHub yıldızı). Varsayılan olarak bu dosyaların hepsi tek bir klasöre, docs/superpowers/'a düşer. Haziran ayında bir Python finans kütüphanesi olan Okama'nın maintainer'ları, bir agent'ın oraya yazdığı ve plugin'in tam da amaçladığı gibi commit edilmiş sekiz implementasyon planının Read the Docs üzerinde herkese açık web sayfaları olarak render edildiğini fark etti. Bunu release'den sonra fark ettiler.
Şimdi bunu büyütün: on developer'lık bir front-end takımı, dört squad, bir repo, ve her developer bu dosyaları üretiyor. Lead'in masasına üç soru geliyor. Tam olarak neyi versiyonluyoruz? Bir spec, iki sprint önce silinmiş bir path'i işaret ettiğinde drift bir sorun mu? Ve klasörü kim yönetiyor? Okama sızıntısının sebebi commit etmek değildi. Sebebi, kuralsız commit etmekti. Bu makale size beş kural veriyor.
Her araç dosyaları commit eder
Superpowers commit edip etmeyeceğini hiç sormaz. Planlama becerisinin 18. satırı her planı docs/superpowers/plans/ altına, tarihli, özellik başına bir dosya olarak kaydeder. Brainstorming becerisi tasarım dokümanını yazar ve siz planı görmeden aynı adımda commit eder.
Bu bir Superpowers tuhaflığı değil. Her büyük spec-driven araç aynı seçimi yapıyor:
| Araç | Yayıncı | Spec'ler nerede yaşıyor |
|---|---|---|
| Superpowers (286.000 yıldız) | obra | docs/superpowers/, her şey için tek klasör |
| Spec Kit (136.000 yıldız) | GitHub | özellik başına numaralı bir klasör, o özelliğin branch'inde |
| Kiro | Amazon | .kiro/specs/, özellik başına bir klasör |
| AI-native SDLC playbook | Anthropic | aşama başına commit edilen bir artifact: intent, spec, plan, diff, review bulguları, incident kaydı |
Kiro, özellik başına klasörleri takım arkadaşlarının aynı anda farklı özellikler üzerinde birlikte çalışmasının bir yolu olarak satıyor. Ağustos'ta yayınlanan Anthropic'in playbook'u daha da ileri gidiyor: her aşama, sonraki aşamanın okuyabileceği bir artifact commit ediyor. Yani soru hiçbir zaman commit edip etmeyeceğimiz değildi, ve nereye sorusunu her araç cevaplıyor. Dosyayı kimin sahiplendiği ve ne zaman öldüğü ise cevaplanmıyor. Beş kuralın kapattığı boşluk bu.
Yanlış giden üç yol
Commit edilmiş planlar üç farklı şekilde başarısız olur.
Hata 1: docs generator'ı. Bir table of contents onu listelesin ya da listelemesin, docs/ altındaki her markdown dosyasını render eden bir dokümantasyon build'i, plans klasörünü de manuelle birlikte gönderir. Okama'nın başına gelen tam olarak bu.
Hata 2: branch. Superpowers issue 1246, brainstorm'un planı doğrudan main'e commit ettiğini bildiriyor. Bir kullanıcı, session başına 10 ile 15 commit sayıyor, her birkaç değişiklikte bir yenisi. Thread'in isteği tek satıra sığıyor: main branch'te plan ve spec olmasın.
Hata 3: drift. Spec drift, sessiz olan hatadır: kod evrilir, spec evrilmez. Thoughtworks'ten Birgitta Böckeler, spec-driven development'ın üç seviyesini adlandırıyor:
| Seviye | Anlamı |
|---|---|
| Spec-first | Yazılır, bir kez kullanılır |
| Spec-anchored | Özelliğin ömrü boyunca tutulur ve bakımı yapılır |
| Spec-as-source | İnsan sadece spec'i düzenler |
Superpowers spec-first dokümanlar yazar ve onları sonsuza dek tutar. Varsayılan olarak ilk taslak bakımıyla spec-anchored depolama elde edersiniz: dosyayı kimse güncellemez, ve bir agent onu bir sonraki çeyrekte gerçek diye okur. TrueFoundry bunu açıkça söylüyor: drift, spec-first pratikte kaçınılmazdır ve spec-anchored pratikte yönetilebilir, ama yalnızca sapma tespit edilebilirse.
41 spec ve 9 agent dosyası tutan bir repo, düzensizlik sorunu yaşamıyor. 41 versiyonsuz behavior input'u var. Böckeler'in kendi tepkisi: tüm bu markdown dosyalarını değil, kodu review etmeyi tercih ederdi. Bir daha yüklenmeyen bir plan çöptür. Bir agent'ın yüklediği bir plan ise bir talimattır, ve bayat bir talimat yanlış bir talimattır.
Kural 1: squad başına bir yuva, sahipleriyle
Kural 1: klasörün bir sahibi vardır, ve bu sahip plugin değil, bir squad'dır. Sürüm 5'ten itibaren Superpowers, projenizin CLAUDE.md'sindeki talimatları kendi varsayılanlarına tercih ediyor. Plan'ların nereye gideceğini söyleyin, oraya giderler.
Ancak bir path tablosu yeterli değil. Issue 939'da bir kullanıcı bir output-path tablosu yazmış ve model, tablosunu atlayıp becerideki somut path'i takip etmiş. Becerinin kendi override notu bir parantez içinde. Tek, kalın, emir kipiyle yazılmış bir satır ilk denemede sorunu çözdü: spec'ler burada kaydedilmeli, orada değil, ve varsayılan, kaçınılması gereken şey olarak adlandırılıyor.
Yerleşim, squad başına bir klasördür (checkout, search, accounts, design-system), her biri kendi spec'leri ve planlarıyla. Bir monorepo'da bu satırı paket'in kendi CLAUDE.md'sine koyun. Claude Code, bir alt dizinin dosyasını, oradan bir şey okuduğunda talep üzerine yükler, ve dokümantasyon her dizinin sahibinin genellikle kendi dosyasının bakımını yaptığını söylüyor. Plugin'i hiç kurmamış mühendisler bundan etkilenmez: satır sadece bir beceri nereye kaydedeceğini sorduğunda devreye girer.
Sonra platformun sahipliği zorunlu kılmasına bırakın. Squad klasörü başına bir CODEOWNERS satırı, ve her spec review'u onunla yaşayacak kişilere ulaşır. Bir uyarı: override bir prompt'tur, bir ayar değil. Her plugin release'inden sonra ilk spec'i kontrol edin.
Kural 2: kişisel ile paylaşılan
Kural 2: her plan bir takım artifact'ı değildir. Superpowers'tan yapılandırılabilir bir konum isteyen ilk kişi (issue 337) en iyi şekilde söylemiş: plan dosyaları, proje artifact'ları yerine kişisel çalışma dokümanları olabilir.
Kişisel taraf için buna özel bir dosya var. CLAUDE.local.md, paylaşılan dosyanın yanında oturur, ondan sonra yüklenir, ve dokümantasyon onu kendinizin git-ignore etmesini söyler. Özel bir klasöre yönlendirmeniz orada yaşar ve başka kimse görmez. Klasörün kendisi için Git'in, paylaşılan ağaca hiç dokunmayan bir ignore dosyası var: .git/info/exclude clone başınadır, hiç commit edilmez, ve pull request gerektirmez. Plugin bunu kendi scratch alanı için zaten yapıyor: sürüm 6.0.3'ten itibaren çalışma dizini, kendi içine * içeren bir .gitignore bırakıyor, böylece takip edilen bir dosyaya dokunmadan kendini yok sayıyor.
Paylaşılan taraf, brainstorm'un zaten çalıştırdığı review kapısını geçen her şeydir: spec yazılır, review istenir, ikinci bir kişi tarafından onaylanır. Onaylanırsa squad klasörüne taşınır. Onaylanmazsa yerel kalır. İkisi de bir branch'te yazılır, asla main'de değil. Paylaşılan CLAUDE.md'deki iki satır bunu sağlar: spec'leri ve planları bir özelliğin başlangıcı olarak ele alın, ve onları yazmadan önce worktree'yi oluşturun.
Bir sınır: git-ignore edilmiş bir plan seyahat etmez. Okama maintainer'ları önce klasörü ignore etmeyi denedi ve bundan geri döndü, çünkü planlar makineler ve agent'lar arasında senkronize olmayı bıraktı. Kişisel, kişisel demektir.
Kural 3: ADR'ler gibi bir yaşam döngüsü
Kural 3: bir spec'in bir durumu vardır, ve ölü bir spec bunu söyler. Fikir 15 yaşında. Michael Nygard, 2011'de, mimari karar kayıtlarını (ADR'ler) repoda tutmayı, her biri numaralandırılmış tek bir dosya olarak önerdi. Bir karar önce önerilir, sonra kabul edilir. Sonraki bir kayıt onu değiştirdiğinde, eski olan, yerine geçenin referansıyla birlikte deprecated veya superseded olarak işaretlenir. Bir karar geri alınırsa, eski kayıt tutulur ama superseded olarak işaretlenir.
Spec'lere uygulandığında, her paylaşılan spec, agent'ın zaten okuduğu beş satırlık bir header ile açılır:
| Alan | Amaç |
|---|---|
| status | proposed, accepted, superseded |
| superseded-by | yerine geçen spec |
| owner | squad |
| touches | spec'in hakkında iddia yaptığı path'ler |
| review date | son kontrol edildiği tarih |
Kabul edilmiş bir spec'i asla farklı bir karara dönüştürecek şekilde düzenlemeyin. Bir sonrakini yazın, ona geri işaret edin, ve tarih dürüst kalsın. Anthropic'in playbook'unda belirtilen bir istisna var: implementasyon plandan ayrıldığında, planı aynı commit içinde güncelleyin. Plan, onu bozan diff ile birlikte seyahat eder, ve bir hook bunu zorunlu kılabilir.
Spec Kit, bir spec'in yaşayabileceği üç yol adlandırıyor. Flow-forward: özellik başına yeni bir klasör, eskiler geçmiş olarak tutulur. Living spec: spec, sözleşmedir ve gerisi yeniden üretilir. Flow-back: build, spec'i yeniden şekillendirir. Kuralları, task'larda veya kodda spec'in hâlâ farklı bir şey söylediği bir değişikliği bırakmamak. Bu, bilerek spec-anchored seçmek demek.
Sınır şu: status, bir insanın belirlediği metadata'dır. CLAUDE.md'niz söylemedikçe agent kendi spec'ini superseded olarak işaretlemez, ve söylese bile review bunu fark etmek zorundadır.
Kural 4: CI'da bir drift kapısı
Kural 4: ağaç hakkında yalan söyleyen bir spec, build'i başarısız yapar. Haziran'da yayınlanan, sorunu adlandıran makale buna sessiz spec-code drift diyor: kod evrilir, spec evrilmez, ve sapma, düzeltmek maliyetli hale gelene kadar görünmez kalır. Cevabı, engelleyici bir merge koşulu olan bir drift kapısıdır.
Kontrol göründüğünden daha küçük. Header'ı accepted diyen her spec için, adlandırdığı path'leri, backtick içinde veya touches satırında, çekin ve her birinin var olduğunu test edin. Eksik path, başarısız build, log'da spec'in adıyla birlikte. Superseded ve proposed dosyalar atlanır: yalnızca accepted spec'ler ağaç hakkında iddia yapar, dolayısıyla yalnızca accepted spec'ler kontrol edilir. TrueFoundry bunu incident sonrası arkeoloji yerine zamanlanmış bir diff olarak çerçeveliyor: bir spec bir iskelettir, ve bir spec değişikliği bir policy değişikliğidir.
İnsanlar zaten manuel versiyonu çalıştırıyor. Bir yorumcu, Claude'a spec dosyalarını codebase ile karşılaştırmasını ve eksik olan şeyler için ticket açmasını yaptırıyor. Script, bunu her pull request'te, bedavaya yapar.
İkinci koruma, Okama'nın sevk ettiği: klasörü docs build'inden hariç tutun. Sphinx konfigürasyonundaki bir satır, dosyaları Git'te tutup HTML'in dışında bırakır.
Sınır şu: bir path kontrolü, silinmiş dosyaları yakalar, değişmiş davranışı değil. Bir spec, var olan her dosyayı adlandırabilir ve hâlâ artık var olmayan bir API'yi tarif edebilir. Review ve same-commit kuralı bunun için var.
Kural 5: bir boyut bütçesi, ve maliyet
Kural 5: işlerin çoğu bir spec'i hak etmez. Spec-driven overhead üzerine kanıtlar tutarlı:
| Deney | Sonuç |
|---|---|
| Marmelab, geçerli tarihi gösteren bir özellikte Spec Kit | 8 dosya, 1.300 satır spesifikasyon metni |
| OpenSpec bake-off, aynı gereksinimler bir spec aracıyla vs sadece Claude Code ile | %50 daha fazla kod, %50 daha fazla cyclomatic complexity, iki kat süre, üç kat maliyet |
| Aylarca spec-driven development çalıştıran bir takım | 2 ile 3 kat token, yaklaşık iki kat süre, hiç gerekmeyen değişiklikler için büyük koordinasyon maliyeti; kodun iyileştiğine dair kanıt yok |
Bake-off tek bir deney, bir benchmark değil, ve yazarı da bunu söylüyor. Ama yön değişmiyor. Dolayısıyla kural: iş bir squad sınırını aştığında veya 90 gün içinde tekrar okunacaksa bir spec yazın. Gerisi bir prompt'tur.
Superpowers her isteği zaten üç yola ayırıyor: spike, bounded, architectural. Sadece architectural yol bir spec yazar. Bounded yolu bounded tutun, ve spec'i 300 satır civarında tutun. Pratisyenler iki satır ekliyor: spec'i çok büyük yapma, ve üretilen spec'leri oku.
Sınır iki yönde de çalışır. Aynı bake-off, düz çalıştırmanın kaçırdığı üç boşluk buldu. Spec, coverage satın alır, hız değil. Coverage'ın önemli olduğu yerde bunun için ödeyin.
Sonuç: commit et, sonra yönet
Lead'in üç sorusuna geri dönelim. Neyi versiyonluyoruz: onaylanmış spec'ler ve planlar, bir branch'te, squad'ın klasöründe. Drift: bir status header ve bir CI kapısı. Yönetişim: sahipler ve bir boyut kuralı.
Beş kural, ve hiçbiri bugün bir araç tarafından zorunlu kılınmıyor. Override issue'su açık. Main-branch issue'su açık. Talimatı yeniden sıralayan pull request, merge edilmeden kapatıldı. Yanan takım, pratiği sürdürdü: 8 plan ve 6 spec, commit edilmiş, docs build'inden hariç tutulmuş.
Böckeler'in itirazı geçerliliğini koruyor. Bir status header ve bir boyut bütçesiyle, yalnızca accepted spec'leri okursunuz, ve daha azını. Geri kalanı, Anthropic'in playbook'unun audit trail dediği şeydir: kimin ne istediği, agent'ın ne ürettiği, ve kimin onayladığı.
Bu bir süreçtir, bir araç değil: bir CLAUDE.md dosyası, bir CODEOWNERS dosyası, bir header, ve on beş satırlık bir script. Ve takım bir CODEOWNERS talebini review etmeyecekse, bir spec'i de review etmeyecektir. O durumda .gitignore dürüst seçim olurdu.
AIDive