Refactor'un belirtisi yok — Claude yanıldığında göremezsin. Üç korkuluk: test, atomik commit, elle tıklama.
Refactor, Claude'un en tehlikeli olduğu iş. Bug'ın belirtileri vardır — düğme tıklamaya tepki vermiyor, değer undefined, stack trace — böylece Claude'un çözümünün doğru olup olmadığını anlarsın. Refactor'un yok. "Hâlâ çalışıyor" şunu demek olabilir: "testler hâlâ geçiyor," ama davranış sessizce değişti, fark etmedin ve bir hafta sonra prodüksiyon patlar.
Yakın zamanda how2claude'da Claude ile oldukça büyük bir refactor yaptım: x402 kripto ödemelerini elle yazılmış PaymentHandler + FacilitatorClient'tan (139 satır) x402-rails gem'ine geçirdim ve aynı anda iki controller'da tekrarlanan Purchase.create! / Subscription.create! alan eşlemesini model sınıf metodlarına çıkardım. Bir commit, 4 dosya değişti, 2 silindi, 2 eklendi.
Prompt'um tek kelimeydi: "refactor."
Bu kadar kısa olabilmesinin sebebi etrafında güvenlik korkulukları olmasıydı.
Branch o noktaya geldiğinde 221 test vardı. Ödeme akışındaki tüm kritik yollar kapsanmıştı.
Claude'un refactor'dan önceki varsayılan davranışı "önce testleri incele" değil. O yüzden önce bin/rails test çalıştırmasını, yeşil olduğunu doğrulamasını ve sonra bir şeye dokunmasını söyledim.
Refactor'dan sonra tekrar çalıştır. Hâlâ yeşil. Bu, regresyon yok demek değil — bilinen davranış bozulmadı demek.
Kod yolunun test kapsamı yoksa, Claude'a mevcut davranışı kilitleyen asgari bir test yazdır. Çalıştır, commit et. Ondan sonra refactor. Aksi takdirde yaptığı refactor değil, rewrite — ve eşdeğerliği doğrulamanın bir yolu yok.
Bu refactor aslında iki şeydi:
Purchase / Subscription alan eşlemesi: controller → model sınıf metodlarıFrontend'de üçüncü bir şey daha vardı: JS tarafı imzalama akışını viem + x402-fetch ile yeniden yazmak.
Claude'a doğal sınırlarda böldürdüm: backend + model çıkarımı bir commit'te (9f3e239), frontend ayrı bir commit'te (93746d8). Her commit tam açıklama, dosya listesi ve gerekçe taşır.
Faydalar:
- Diff'ler okunabilir kalır. Bir commit, bir şey.
- Rollback tanecikliği. Prodüksiyonda frontend bug'ı çıkarsa git revert 93746d8 sadece frontend'i geri alır, backend'i bırakır.
- Claude'un kendi dikkati odaklı kalır. Bir commit, bir şey — dikkati de sadece o şeyi kapsar.
Refactor tamamlandığında Claude'u durdurup git diff --staged'i bana göstertirim. Testleri koşma. Uygulamayı çalıştırma. Önce diff'i oku.
Taradığım sinyaller:
app/services/x402/payment_handler.rb tamamen silinmiş — tamam, gem'e geçmenin amacı bu. Ama dokunmasını istemediğim bir şeyi silmişse durup soruyorum.Purchase.create!(wallet_address: verify_result["payer"], ...) → Purchase.record_x402!(payment:, settlement:) artık payment[:payer] okuyor. Kaynak değişti (gem'in request.env'i vs eski client'ın dönüş değeri), ama alanlar bire bir eşleşmeli.Tuzak 1: gem'in Stimulus controller'ları sessizce yüklenmedi
x402-rails gem'i kendi Stimulus controller'larını getiriyor. Claude kodu yazdı, testler yeşil geçti. Ödeme düğmesine elle tıkladım — hiçbir şey olmadı.
Sebep: config/importmap.rb içinde @hotwired/stimulus için olan pin mevcut olmayan bir vendor dosyasına işaret ediyordu ve importmap o pin'i sessizce attı. gem'in controller'ları hiç yüklenmedi. Testler bunu yakalayamaz çünkü bin/rails test JS çalıştırmaz.
Tuzak 2: YAML 0x...'i integer olarak parse etti
wallet_address: 0x833589... — tırnaksız. YAML 0x önekini görüp hexadecimal integer olarak okudu. Facilitator string olmayan bir değer aldı ve reddetti. Claude config'i yazarken YAML parse kurallarını düşünmedi.
İki tuzak da gerçek düğmeye tıkladığım için yakalandı. Testlerin geçmesi, özelliğin çalışmasıyla aynı şey değil. Refactor sonrası manuel doğrulama isteğe bağlı değil.
Refactor, "Claude'a direksiyonu ver" senaryolarının en riskli olanı. Korkuluklar Claude için değil. Senin için — Claude bir şeyi yanlış yaptığında, prodüksiyon yangınında değil, 5 dakika içinde yakalayabilesin diye.