Insting saat menghadapi fitur kompleks adalah "coba saja dulu" — tapi keputusan arsitektur bersembunyi di model ketiga, edge case kelima. Nilai sejati plan mode adalah memindahkan percakapan setingkat arsitektur ke teks sebelum kode. Kasus nyata: sistem juri komunitas Pickful — 3.032 baris, 119 spec hijau, satu commit, nol kerja ulang arsitektur setelahnya.
Di hadapan fitur kompleks, insting mayoritas orang adalah "coba dulu yang simpel".
Masalahnya: sistem kompleks punya satu karakteristik — keputusan arsitektur bersembunyi di model ke-3, di edge case ke-5, di aturan poin ke-8. Menceburkan diri ke dalam kode dan menabrak keputusan itu di tengah jalan, lalu kembali mengubahnya, harganya 10× lipat dibandingkan dibicarakan lebih dulu di level teks.
Saya memakai plan mode Claude Code untuk membangun TopicReview, sistem juri komunitas di Pickful, dan melihat versi ekstrem dari ketimpangan ini: satu commit, 3.032 baris, 119 spec hijau, dikirim sekali jalan. Tak ada satu pun dari belasan commit berikutnya yang merupakan kerja ulang arsitektur — semuanya penyetelan parameter, pemolesan UI, tambalan edge case. Sistem berjalan stabil sejak itu dan kini menjadi inti cara komunitas memoderasi dirinya sendiri.
Tulisan ini membahas mengapa fitur kompleks butuh plan mode dulu, apa yang sesungguhnya dilakukan fase plan, dan kapan percakapan cukup matang untuk mulai menulis kode.
TopicReview adalah pemungutan suara komunitas untuk memutuskan apakah sebuah post berkualitas rendah dihapus. Satu kalimat untuk diutarakan — tapi spesifikasinya terbuka berlapis-lapis:
Inti kompleksitasnya tidak di satu aturan — melainkan di bagaimana aturan saling berinteraksi. Setiap aturan yang ditambah bisa memicu rollback di tempat lain.
Saat menulis langsung, masalah tersulit bukan fakta yang kelihatan — tapi pertanyaan yang tak pernah terpikir untuk ditanyakan. Membaca kode TopicReview terbalik, setidaknya ada empat tembok yang pasti akan menabrakmu kalau plan dilewati:
Aturan kelayakan juri. Terlihat hanya seperti User.jurors_and_judges.sample(12). Namun aturan sebenarnya: kecualikan penulis post, kecualikan pelapor post, kecualikan yang sudah memilih di ronde awal (agar tidak memilih lagi di banding). Tiga pengecualian menumpuk. Menulis model sekaligus, kamu akan melewatkan satu-dua.
Pembayaran poin tertunda. Putusan remove biasanya memicu pembayaran ke juri. Tapi banding bisa membatalkan remove — dan ketika dibatalkan, juri yang memilih seiring putusan lama kini salah pihak, sehingga pembayaran harus dihitung ulang terhadap putusan baru. Maka putusan remove harus menunggu jendela banding 24h tutup dulu sebelum membayar juri. Lewati menulis aturan ini, bayar duluan, lalu kamu akan mencoba menarik kembali poin — 10× lebih berantakan daripada membayar terlambat.
Desain antarmuka job terjadwal. CloseTopicReviewJob terlihat seperti "mengakhiri sebuah review". Dalam praktiknya ia menangani tiga situasi:
# Jendela voting awal berakhir
CloseTopicReviewJob.set(wait_until: voting_ends_at).perform_later(review.id)
# Pembayaran juri tertunda setelah putusan remove
CloseTopicReviewJob.set(wait: 24.hours).perform_later(review.id, award_juror_points: true)
# Jendela banding berakhir
CloseTopicReviewJob.set(wait: 24.hours).perform_later(review.id, appeal_id: appeal.id)
Tanpa perencanaan di depan, kamu menulis signature pertama, dan di kasus kedua menyadari antarmuka harus berubah.
Tembok termahal: bisakah banding saat removal provisional? Saat suara remove melewati ambang, post langsung disembunyikan (provisional), tapi keseluruhan review masih di status voting — belum decided. Bisakah user banding sekarang?
decided dan appealedSatu keputusan itu merambat ke belakang dan mengubah pemeriksaan parameter dalam open_appeal! dan logika state machine. Memutuskan di tengah jalan = menulis ulang setengah sistem.
Plan mode Claude Code adalah mode di mana menulis kode tidak diizinkan — Claude boleh membaca repo, memikirkan pendekatan, berdiskusi denganmu, tapi setiap modifikasi file di-hard-block sampai kamu menyetujui sebuah plan.
Pembatasan mekanis itulah intinya: ia memaksa percakapan setingkat arsitektur terjadi dalam teks.
Beberapa hal yang dilakukan fase plan dalam praktik:
1. Menggambar state machine dan peran. 5 status, 4 peran (juri / hakim / penulis post / pelapor), apa yang bisa dan tidak bisa dilakukan tiap peran di tiap status — semua dalam beberapa baris markdown. Beberapa baris vs. puluhan file. Biaya perubahan berbeda dua orde besar.
2. Menelusuri alur tiap peran:
Di mana pun penelusuran mandek, muncul pertanyaan tersembunyi: "apakah juri melihat vote juri lain?", "apa yang bisa dilakukan penulis saat removal provisional?"
3. Menginterogasi edge case. Fase plan bukan mendesain "jalur normal" — ia dengan sengaja mengajukan pertanyaan yang biasanya tidak muncul:
finalize bersamaan — apakah race menggandakan pembayaran? (Tambahkan field juror_points_awarded untuk idempotensi.)95% pertanyaan ini tidak muncul secara alami saat menulis kode. Fase plan memaksa menjawabnya satu per satu.
4. Buku besar poin. Sistem poin cukup kompleks hingga diskusi saja tidak cukup — kamu harus benar-benar menggambar tabel: setiap aliran poin dengan pemicu, jumlah, dan jalur rollback-nya. Begitu buku besar seimbang, semua edge case (refund provisional, refund banding, bonus) dapat direkonsiliasi.
Standar yang keras:
closed (keep / remove / warn × banding / tidak × provisional / tidak) — kamu bisa menceritakannya dari ujung ke ujungKetika standar ini tercapai, menulis kode menjadi menerjemahkan plan ke Ruby.
Ship pertama sistem ini:
d162f1e Add community moderation system with jury/judge review and appeals
63 files changed, 3032 insertions(+)
119 specs, 0 failures
63 file, 3.032 baris, 119 spec hijau. Dikirim sekali jalan.
Belasan commit berikutnya membuktikan arsitekturnya bertahan:
Apply legacy penalty (1pt) for posts created before 2026-03-26
Fix topic review appeal bugs: window mismatch and verdict not updated
Add topic_removed status for posts removed by community review
Default to keep verdict when review expires with zero votes
Reduce provisional removal penalty to 1pt during trial period
Allow topic creator to withdraw active reviews
Add handled tab to jury dashboard, fix tabs styling
Masing-masing adalah tuning / fix / polish / fitur kecil. Tak satu pun "kembali mendesain ulang state machine" atau "model poin perlu diubah". Kerangka tulangnya benar sepenuhnya.
Inilah imbalan sesungguhnya dari plan: eksekusi tidak terganggu. Tidak ada "tunggu, jalur ini bagaimana" — plan sudah mencakupnya. Tidak ada "edge case ini belum saya pikirkan" — fase plan sudah menanyakannya. Tidak ada "antarmuka ini harus didesain ulang" — plan sudah merapikannya.
Berjam-jam menulis kode, hanya melakukan satu hal: menerjemahkan desain yang jelas ke papan ketik.
Tidak semua tugas layak plan:
Keuntungan plan mode datang dari menurunkan biaya penulisan ulang. Bila tugas tak punya risiko penulisan ulang, plan hanyalah overhead.
"Pikirkan dulu sebelum bertindak" terdengar seperti nasihat kepribadian. Plan mode bukan soal itu.
Plan mode adalah membuat percakapan setingkat arsitektur terjadi di tempat 10 kata bisa mengubahnya — bukan di tempat 30 file harus diubah.
Di bawah kompleksitas, pepatah lama industri "words are cheap, code is expensive" perlu dibalik — bukan berarti "tulis saja kode dulu dan lihat" (itu cuma berlaku saat selisih biaya kecil), melainkan memanfaatkan selisih biaya itu: menempatkan percakapan mahal di depan, dalam medium murah.
3.000 baris dalam satu commit terasa hebat. Bukan karena saya menulis cepat — tapi karena plan mengubah "menulis" menjadi tindakan yang murni mekanis.