RFC #
Keputusan teknis yang paling mahal bukan yang salah dari awal — melainkan yang salah setelah ratusan jam coding, testing, dan deployment sudah dilakukan. RFC, singkatan dari Request for Comments, adalah mekanisme yang digunakan tim engineering untuk mencegah skenario itu: sebuah perubahan besar dipikirkan bersama, didiskusikan secara terbuka, dan didokumentasikan sebelum satu baris kode pun ditulis. Praktik ini bukan birokrasi — ia adalah investasi murah untuk menghindari rework yang mahal. Artikel ini membahas apa itu RFC, mengapa ia penting, kapan harus dibuat, bagaimana struktur yang efektif, dan anti-pattern apa yang membuat RFC menjadi sia-sia.
Apa Itu RFC? #
RFC dalam konteks software engineering adalah dokumen tertulis yang digunakan untuk mengusulkan, mendiskusikan, dan mendokumentasikan perubahan teknis yang signifikan sebelum perubahan tersebut diimplementasikan. Kata kuncinya ada dua: sebelum dan signifikan. RFC bukan post-mortem, bukan dokumentasi teknis akhir, dan bukan pengganti PR description. Ia adalah alat pengambilan keputusan kolektif.
Istilah RFC awalnya berasal dari dunia standar internet (IETF), tempat hampir semua protokol fundamental yang kamu gunakan setiap hari — HTTP, TCP, DNS — lahir dari proses RFC yang panjang. Dunia software engineering modern mengadaptasi spirit yang sama: Google, Meta, Netflix, Stripe, dan Shopify semuanya memiliki proses RFC internal sebagai bagian dari engineering culture mereka.
Cakupan RFC bisa sangat beragam:
Perubahan yang biasanya butuh RFC:
✓ Perubahan arsitektur sistem (monolith → microservices, penambahan message broker)
✓ Perubahan atau penambahan API yang dikonsumsi banyak pihak
✓ Perubahan database schema yang berdampak luas
✓ Adopsi teknologi atau library baru di level platform
✓ Perubahan pada sistem kritis (auth, payment, data pipeline)
✓ Strategi migration atau deprecation yang panjang
Perubahan yang TIDAK perlu RFC:
✗ Bug fix yang lokaliasi dan minim dampak
✗ Refactoring internal tanpa perubahan perilaku eksternal
✗ Penambahan fitur kecil yang cakupannya terbatas satu service
✗ Update dependency rutin
✗ Perubahan konfigurasi yang mudah di-rollback
Mengapa RFC Penting #
Keputusan Teknis Punya Konsekuensi Jangka Panjang #
Perubahan arsitektur yang terlihat kecil hari ini bisa menjadi hambatan besar dua tahun ke depan. Pilihan database schema yang tidak dipikirkan matang bisa memaksa tim melakukan migration besar saat sistem sudah memiliki jutaan baris data. RFC memaksa engineer untuk berpikir melampaui “bagaimana membuatnya bekerja sekarang” menuju “bagaimana ini akan berperilaku saat skala 10x lebih besar, saat tim berganti, dan saat requirement berubah.”
Tanpa RFC — skenario umum:
Sprint 3: Engineer A memutuskan arsitektur caching sendiri, langsung coding
Sprint 5: Engineer B butuh extend sistem, tapi tidak paham asumsi yang dibuat
Sprint 8: Race condition ditemukan di production — asumsi Engineer A tidak scalable
Sprint 9: Refactor besar, 3 minggu hilang untuk membongkar keputusan lama
Dengan RFC:
Sprint 3: Engineer A menulis RFC, 3 engineer lain review dalam 2 hari
Sprint 3: Edge case race condition ditemukan di fase review, bukan production
Sprint 4: Implementasi dimulai dengan fondasi yang sudah divalidasi bersama
Sprint 5: Engineer B baca RFC — paham konteks dan asumsinya dalam 30 menit
Menghindari Hero Engineering #
Hero engineering adalah pola di mana satu engineer (biasanya senior) membuat keputusan arsitektur besar secara unilateral, langsung mengimplementasikan, lalu tim lain menyesuaikan diri dengan hasilnya. Pola ini terasa efisien di jangka pendek tapi berbahaya di jangka panjang.
// ANTI-PATTERN: Hero Engineering
Engineer senior: "Saya sudah implement sistem baru untuk handle messaging.
Ini PR-nya, tolong di-review."
[3000 baris kode baru, arsitektur baru, dependency baru]
Tim: "Kami tidak punya konteks tentang ini, bagaimana cara review-nya?"
→ Review superfisial, kode di-merge, masalah baru muncul kemudian
// BENAR: RFC sebelum implementasi
Engineer senior: "Saya punya proposal untuk sistem messaging baru.
Ini RFC-nya, mohon feedback sebelum kita commit ke implementasi."
[Dokumen 3 halaman, diagram, alternatif yang dipertimbangkan]
Tim: "Bagian ini rawan race condition. Bagaimana kalau kita gunakan approach X?"
Engineer senior: "Poin bagus, saya revisi proposal-nya."
→ Keputusan lebih solid, seluruh tim punya konteks
RFC secara struktural mendistribusikan ownership keputusan teknis — bukan hanya ke satu orang, tapi ke seluruh tim yang terlibat. Ini penting untuk resiliensi tim saat orang-orang berganti.
Dokumentasi Keputusan, Bukan Hanya Kode #
Kode mendokumentasikan apa yang dibangun. RFC mendokumentasikan mengapa — konteks, alternatif yang sudah dipertimbangkan, trade-off yang disadari, dan asumsi yang dibuat saat keputusan diambil.
Pertanyaan yang sering muncul 1–2 tahun setelah implementasi:
"Kenapa kita pakai approach ini padahal ada yang lebih sederhana?"
"Kenapa database-nya dipisah, kan bisa disatukan?"
"Kenapa kita tidak pakai library X yang lebih populer?"
Tanpa RFC: tidak ada yang bisa menjawab, atau jawabannya "dulu ada alasannya
tapi sudah lupa", atau "tanya si A tapi dia sudah resign"
Dengan RFC: jawaban ada di dokumen — konteks saat itu, alternatif yang ditolak,
alasan teknis dan bisnis yang mendasari keputusan
Diskusi Asinkron yang Scalable #
Meeting sinkron untuk membahas keputusan arsitektur punya banyak kelemahan: tidak semua orang bisa hadir, diskusi sulit dilacak, keputusan akhir sering tidak terdokumentasi, dan engineer introvert jarang bisa berkontribusi optimal dalam format real-time.
RFC secara natural mendukung diskusi asinkron — reviewer bisa memberikan komentar kapan pun, penulis RFC punya waktu untuk merespon dengan matang, dan seluruh thread diskusi tersimpan sebagai bagian dari dokumen keputusan.
Tim yang tersebar di beberapa zona waktu mendapat manfaat besar dari RFC. Tidak ada yang harus hadir di meeting jam 2 pagi — reviewer bisa memberikan masukan di waktu kerja normal mereka, dan diskusi tetap berjalan secara efektif.
Kapan Membuat RFC #
Rule of thumb yang sederhana: jika perubahan sulit dijelaskan dalam satu paragraf, atau jika ada lebih dari satu cara yang valid untuk melakukannya, kemungkinan besar butuh RFC.
Beberapa trigger yang lebih spesifik:
BUAT RFC jika perubahan:
□ Berdampak ke lebih dari satu service atau tim
□ Mengubah kontrak API yang sudah dikonsumsi pihak lain
□ Mengubah atau menambahkan kolom/tabel di database yang shared
□ Memperkenalkan teknologi, library, atau pola baru di level platform
□ Sulit atau mahal untuk di-rollback jika ternyata salah
□ Akan berdampak ke performa atau cost secara signifikan
□ Menyentuh sistem yang critical (autentikasi, otorisasi, transaksi finansial)
□ Merupakan keputusan yang akan mempengaruhi arsitektur jangka panjang
TIDAK PERLU RFC jika perubahan:
□ Bug fix yang terlokalisasi di satu service
□ Refactoring internal tanpa perubahan perilaku yang terlihat dari luar
□ Update dependency minor yang sudah ada proses standarnya
□ Fitur kecil yang cakupannya jelas dan risikonya rendah
□ Perubahan yang mudah di-rollback dalam hitungan menit
Tidak ada threshold yang absolut — gunakan judgment. Jika kamu ragu apakah perlu RFC, diskusikan dengan satu atau dua rekan terlebih dahulu. Jika diskusi informal itu memunculkan banyak pertanyaan dan perspektif yang berbeda, itu pertanda kuat bahwa RFC dibutuhkan.
Siklus Hidup RFC #
RFC bukan dokumen yang dibuat sekali lalu dilupakan. Ia punya siklus hidup yang perlu diikuti agar tetap bermanfaat.
Draft → Penulis menulis proposal awal, belum siap untuk review publik
│
▼
In Review → RFC dibuka untuk komentar, reviewer aktif memberikan feedback
│
├── Revisi → Penulis merespon komentar, merevisi proposal
│ └──────────────── (bisa berulang beberapa kali)
│
▼
Accepted → Konsensus tercapai, implementasi boleh dimulai
│
▼
Implemented → Perubahan sudah live di production, RFC diupdate dengan catatan hasil
│
└── atau ──→ Rejected → RFC ditolak, alasan penolakan didokumentasikan
(ini bukan kegagalan — ini informasi berharga)
RFC yang di-Rejected sama berharganya dengan yang Accepted. Ia mendokumentasikan ide yang sudah dipertimbangkan dan mengapa tidak dipilih — mencegah ide yang sama diusulkan ulang tanpa konteks.
Struktur RFC yang Efektif #
RFC yang baik mengikuti struktur yang konsisten sehingga reviewer tahu ke mana harus melihat informasi yang mereka butuhkan. Berikut template yang bisa langsung digunakan:
Header #
# RFC: [Judul Singkat dan Deskriptif]
**Status:** Draft | In Review | Accepted | Rejected | Implemented
**Author:** [Nama] ([tim/squad])
**Reviewer:** [Nama 1], [Nama 2], [Nama 3]
**Dibuat:** YYYY-MM-DD
**Terakhir diupdate:** YYYY-MM-DD
Judul RFC harus bisa berdiri sendiri — seseorang yang melihat daftar RFC harus bisa memahami topiknya hanya dari judul.
// ✗ Judul yang buruk:
"Perbaikan sistem"
"Proposal baru"
"RFC untuk fitur upload"
// ✓ Judul yang baik:
"RFC: Migrasi File Upload ke Asynchronous Processing dengan Job Queue"
"RFC: Pengenalan Event Sourcing untuk Audit Trail Transaksi"
"RFC: Strategi Database Sharding untuk Tabel Orders"
Latar Belakang #
Bagian ini menjelaskan kondisi saat ini dan konteks yang membuat RFC ini diperlukan. Tulis untuk audiens yang tidak familiar dengan detail sistem — jangan asumsikan reviewer sudah tahu semua yang kamu tahu.
## Latar Belakang
Saat ini, proses upload file Excel untuk data impor produk dilakukan secara
synchronous di dalam request HTTP. File diproses langsung oleh web server
yang menangani request tersebut. Rata-rata waktu pemrosesan untuk file
berukuran 5MB adalah 3–5 menit, dengan outlier hingga 8 menit untuk file
yang kompleks.
Ini menyebabkan dua masalah utama:
1. Request timeout (Nginx timeout dikonfigurasi di 60 detik)
2. Web server thread ter-block selama proses berlangsung, mengurangi
kapasitas untuk menangani request lain
Problem Statement #
Nyatakan masalah secara eksplisit dan terukur. Hindari menggabungkan problem statement dengan solusi — bagian ini hanya tentang masalahnya.
## Problem Statement
Sistem upload file saat ini memiliki tiga masalah yang terukur:
1. **Reliability:** 23% dari upload file >3MB gagal karena timeout dalam
30 hari terakhir (berdasarkan log Nginx)
2. **User experience:** User tidak mendapat feedback selama proses upload
berlangsung — tidak ada progress indicator, tidak ada notifikasi selesai
3. **Scalability:** Setiap upload aktif mem-block satu thread web server.
Dengan 10 upload concurrent, kapasitas server untuk request lain
berkurang signifikan
Tujuan dan Non-Tujuan #
Bagian ini sering dilewatkan tapi sangat penting untuk mencegah scope creep dan menyamakan ekspektasi.
## Tujuan
- Upload file berhasil terlepas dari ukuran file (sampai batas yang ditentukan)
- User mendapat notifikasi (email atau in-app) saat proses selesai atau gagal
- Web server tidak ter-block selama pemrosesan berlangsung
## Non-Tujuan
- RFC ini TIDAK membahas validasi konten file (sudah dihandle di layer terpisah)
- RFC ini TIDAK membahas sistem notifikasi secara umum — hanya untuk
notifikasi upload file
- RFC ini TIDAK mengubah format atau schema file yang diterima
Proposal Solusi #
Ini adalah inti RFC. Jelaskan solusi yang diusulkan dengan cukup detail agar reviewer bisa mengevaluasinya, tapi jangan sampai ke level detail implementasi kode yang bisa berubah.
## Proposal Solusi
### High-Level Design
Upload file akan diubah menjadi proses dua tahap:
1. **Tahap penerimaan:** HTTP request hanya menyimpan file ke object storage
(GCS) dan membuat job record di database dengan status "pending"
2. **Tahap pemrosesan:** Background worker mengambil job dari queue,
memproses file, dan mengupdate status job
### Komponen yang Terlibat
HTTP Request
│
▼
API Server ──── simpan file ────► GCS (Object Storage)
│
└── buat job record ─────────► Database (jobs table)
│
▼
Job Queue (Redis/Pub-Sub)
│
▼
Background Worker
│
├── proses file dari GCS
├── update job status
└── kirim notifikasi ke user
### Schema Perubahan Database
Tabel baru: `import_jobs`
- id (UUID, PK)
- user_id (FK ke users)
- file_path (path di GCS)
- status (pending | processing | done | failed)
- error_message (nullable)
- created_at, updated_at
Alternatif yang Dipertimbangkan #
Ini adalah salah satu bagian paling berharga dalam RFC. Menunjukkan alternatif yang sudah dipikirkan membuktikan bahwa keputusan dibuat secara sadar, bukan karena ketidaktahuan.
## Alternatif yang Dipertimbangkan
### Alternatif 1: Meningkatkan Timeout Server
**Ide:** Naikkan Nginx timeout dari 60 detik menjadi 600 detik.
**Alasan ditolak:** Ini hanya menunda masalah, bukan menyelesaikannya.
File yang lebih besar di masa depan akan mengalami masalah yang sama.
Selain itu, thread web server tetap ter-block selama proses berlangsung,
mempengaruhi kapasitas untuk request lain.
### Alternatif 2: WebSocket untuk Progress Real-Time
**Ide:** Gunakan WebSocket untuk memberikan progress update real-time
selama pemrosesan berlangsung.
**Alasan ditolak:** Menambah kompleksitas infrastruktur yang tidak
sebanding dengan value-nya saat ini. Notifikasi email/in-app sudah
mencukupi kebutuhan user berdasarkan feedback yang dikumpulkan.
WebSocket bisa dipertimbangkan sebagai improvement di fase berikutnya.
### Alternatif 3: Streaming Processing
**Ide:** Proses file secara streaming line-by-line tanpa menyimpan
keseluruhan file terlebih dahulu.
**Alasan ditolak:** File Excel tidak mendukung streaming parsing secara
native. Library yang tersedia membutuhkan seluruh file di memory untuk
parsing. Ini akan memperburuk masalah memory usage, bukan memperbaikinya.
Dampak dan Risiko #
Kejujuran di bagian ini adalah tanda RFC yang matang. Setiap perubahan punya trade-off — tugas RFC adalah mengeksposnya, bukan menyembunyikannya.
## Dampak dan Risiko
### Dampak Positif
- Upload file >3MB tidak lagi timeout
- Web server thread tidak ter-block
- User mendapat notifikasi saat proses selesai
### Risiko dan Mitigasi
**Risiko 1: Job stuck di queue**
Kondisi: Worker crash saat memproses job
Dampak: Job tidak selesai, user tidak mendapat notifikasi
Mitigasi: Implementasi job timeout — job yang tidak selesai dalam 30 menit
secara otomatis di-retry maksimal 3 kali, lalu di-mark sebagai failed
**Risiko 2: Duplikat processing**
Kondisi: User melakukan upload file yang sama dua kali sebelum yang pertama selesai
Dampak: Data duplikat di sistem
Mitigasi: Hash file di-check sebelum job baru dibuat. Jika hash sama dan ada
job aktif, return status job yang sudah ada
**Risiko 3: GCS storage cost**
Kondisi: File yang gagal diproses tetap tersimpan di GCS
Dampak: Storage cost bertambah
Mitigasi: Lifecycle policy di GCS — file yang lebih dari 7 hari dihapus otomatis
Migration dan Rollback Plan #
Bagian ini sering dilupakan padahal sangat krusial, terutama untuk perubahan yang menyentuh data atau sistem yang sudah berjalan.
## Migration Plan
### Fase 1: Persiapan (Sprint N)
- Deploy schema database baru (tabel `import_jobs`)
- Deploy background worker service (tanpa traffic)
- Setup GCS bucket baru untuk file upload
### Fase 2: Parallel Running (Sprint N+1)
- Feature flag: 10% traffic menggunakan flow baru
- Monitor error rate dan latency selama 3 hari
- Jika normal, naikkan ke 50%, lalu 100%
### Rollback Plan
Jika terjadi masalah setelah go-live penuh:
1. Feature flag dikembalikan ke 0% (flow lama aktif kembali)
2. Background worker di-scale down
3. Investigasi dilakukan tanpa downtime
4. Data di tabel `import_jobs` dipertahankan untuk analisis
Estimasi waktu rollback: < 5 menit (hanya perubahan feature flag)
Open Questions #
RFC tidak harus sempurna saat pertama kali ditulis. Bagian ini adalah undangan eksplisit untuk reviewer memberikan masukan.
## Open Questions
1. Apakah Redis atau Google Pub-Sub yang lebih tepat untuk job queue?
Background worker di sini tidak membutuhkan exactly-once guarantee,
tapi Redis lebih familiar bagi tim saat ini.
2. Berapa batas maksimum ukuran file yang sebaiknya kita set?
Proposal awal: 50MB. Apakah ini cukup untuk use case yang ada?
3. Apakah notifikasi email sudah cukup, atau perlu juga in-app notification?
Butuh input dari Product tentang ekspektasi user.
Best Practice Menulis RFC #
1. Tulis untuk Audiens yang Tidak Familiar #
RFC yang baik bisa dipahami oleh engineer yang tidak terlibat langsung dalam pengembangan sistem tersebut. Jangan asumsikan konteks — jelaskan singkat setiap komponen yang disebutkan.
// ✗ Terlalu asumtif:
"Kita akan tambahkan consumer baru di Kafka topic `order-events`
yang sudah di-setup di sprint 14."
// ✓ Memberikan konteks:
"Kita akan menambahkan consumer baru untuk Kafka topic `order-events`.
Topic ini digunakan untuk menyiarkan setiap perubahan status order
dan saat ini dikonsumsi oleh dua service: notification-service
dan analytics-service."
2. Fokus ke “Mengapa”, Bukan “Bagaimana” #
Detail implementasi kode bisa berubah seiring development berlangsung. Tapi alasan mengapa keputusan ini diambil, constraint yang ada, dan trade-off yang disadari — ini yang perlu didokumentasikan.
// ✗ Terlalu fokus ke implementasi detail:
"Kita akan menggunakan goroutine pool dengan size 10 yang dibuat
menggunakan sync.WaitGroup dan channel buffered berukuran 100..."
// ✓ Fokus ke keputusan dan alasannya:
"Processing akan dilakukan secara concurrent untuk meningkatkan throughput.
Concurrency level akan dikonfigurasi lewat environment variable (default: 10)
agar bisa di-tune tanpa deploy ulang berdasarkan observasi di production."
3. Jujur tentang Ketidakpastian #
RFC yang terlalu percaya diri dan tidak mengakui ketidakpastian justru kurang dipercaya. Gunakan bahasa yang jujur tentang apa yang sudah diketahui dan apa yang masih perlu divalidasi.
// ✗ Terlalu confident tanpa data:
"Dengan approach ini, latency akan turun 80% dan throughput naik 3x."
// ✓ Jujur tentang basis estimasi:
"Berdasarkan benchmark lokal dengan data sample, kita ekspektasikan
latency turun 50–70%. Angka pasti akan divalidasi setelah load testing
di staging environment."
4. Jaga Panjang RFC Proporsional #
RFC bukan tempat untuk menulis semua yang kamu ketahui tentang topik tersebut. Terlalu panjang sama buruknya dengan terlalu pendek — reviewer kehilangan motivasi untuk membaca sampai selesai.
Panduan panjang RFC berdasarkan kompleksitas perubahan:
Perubahan sederhana tapi perlu dokumentasi:
Target: 1–2 halaman, bisa dibaca dalam 10 menit
Perubahan signifikan (arsitektur baru, migration besar):
Target: 3–5 halaman, bisa dibaca dalam 20–30 menit
Perubahan sangat besar (platform-level change):
Target: 5–8 halaman maksimum
Pertimbangkan memecah menjadi beberapa RFC yang lebih kecil
5. Update RFC Setelah Implementasi #
RFC yang berhenti di status “Accepted” tanpa update setelah implementasi kehilangan sebagian nilainya. Tambahkan catatan singkat di bagian akhir setelah sistem live:
## Catatan Implementasi (diisi setelah go-live)
**Tanggal live:** 2024-03-15
**Status:** Implemented
**Perbedaan dari proposal:**
- Job queue akhirnya menggunakan Google Pub-Sub, bukan Redis,
karena sudah ada infrastruktur Pub-Sub yang dikelola tim platform
- Batas file dinaikkan menjadi 100MB setelah diskusi dengan Product
**Hasil observasi (2 minggu setelah go-live):**
- Error rate upload turun dari 23% menjadi 0.3%
- P95 latency API endpoint upload: 800ms (sebelumnya 3–5 menit)
- Tidak ada incident terkait fitur ini
RFC yang diimplementasikan tapi tidak diupdate statusnya adalah RFC zombie — ia masih ada di sistem tapi tidak lagi mencerminkan realita. Ini mempersulit orang yang membaca RFC di masa depan untuk memahami apakah ini masih relevan atau sudah berubah. Selalu update status dan tambahkan catatan setelah implementasi.
Anti-Pattern RFC yang Harus Dihindari #
RFC sebagai Formalitas #
Ini adalah anti-pattern paling umum: RFC dibuat karena ada aturan “harus ada RFC”, tapi tanpa niat sungguh-sungguh untuk mendapat feedback yang berarti.
// ✗ RFC formalitas:
RFC ditulis setelah implementasi selesai
Reviewer diminta approve dalam 24 jam ("cuma formalitas kok")
Komentar reviewer diabaikan atau dijawab defensif
Status berubah dari Draft langsung ke Implemented
// ✓ RFC yang genuine:
RFC ditulis sebelum satu baris kode implementasi
Reviewer diberi waktu cukup (minimal 3–5 hari kerja)
Komentar direspon dengan serius, proposal direvisi jika diperlukan
Perubahan signifikan dari review didiskusikan, bukan diakali
Terlalu Detail di Level Kode #
RFC yang berisi pseudocode panjang atau detail implementasi spesifik terlalu mudah menjadi usang — saat kode aktual ditulis, implementasinya sering berubah dari proposal. Ini membuat RFC tidak akurat dan menyesatkan.
// ✗ Terlalu detail:
```go
func ProcessUpload(ctx context.Context, fileID string) error {
// detail implementasi 50 baris di RFC
}
→ Kode aktual berbeda, RFC menyesatkan pembaca masa depan
// ✓ Level yang tepat: “Worker akan mengimplementasikan retry dengan exponential backoff (maksimal 3 retry, dengan base delay 1 menit). Setiap retry akan di-log dengan level WARN beserta error context untuk debugging.”
### Tidak Ada Alternatif
RFC tanpa bagian alternatif yang dipertimbangkan terasa seperti pengumuman, bukan proposal. Ia tidak memberikan ruang bagi reviewer untuk mengevaluasi apakah ini benar-benar keputusan terbaik.
// ✗ RFC tanpa alternatif: “Kita akan gunakan Redis untuk caching.” [Tidak ada pembahasan mengapa bukan Memcached, CDN, atau in-memory cache]
// ✓ RFC dengan alternatif: “Kita akan gunakan Redis untuk caching. Alternatif yang dipertimbangkan:
- Memcached: ditolak karena tidak mendukung data structure kompleks yang kita butuhkan
- In-memory cache: ditolak karena tidak shared antar instance saat horizontal scaling
- CDN caching: ditolak karena data yang di-cache adalah user-specific, tidak cocok untuk CDN”
### Reviewer Tidak Dilibatkan Sejak Awal
RFC yang dikirim ke reviewer saat sudah "hampir final" sering kali tidak mendapat feedback yang substansial. Reviewer merasa enggan memberikan masukan besar karena terasa seperti membuang kerja yang sudah dilakukan penulis.
// ✗ Pola yang kurang efektif:
- Penulis menulis RFC lengkap sendiri (3 hari)
- RFC dikirim ke reviewer dengan deadline review 2 hari
- Reviewer hanya memberikan komentar minor karena sungkan
- RFC di-approve, implementasi dimulai
- Masalah besar ditemukan saat implementation — sesuatu yang reviewer sebenarnya ingin tanyakan tapi merasa terlambat
// ✓ Pola yang lebih baik:
- Penulis menulis outline RFC dan problem statement (setengah hari)
- Diskusi singkat dengan 1–2 reviewer kunci: “Apakah ini masalah yang tepat untuk diselesaikan? Apakah ada pendekatan yang sudah kalian pikirkan?”
- Penulis melanjutkan menulis RFC dengan input awal dari reviewer
- RFC disebarkan untuk review formal
- Feedback yang masuk lebih substantif karena reviewer sudah punya konteks
---
## Checklist RFC
SEBELUM MENULIS RFC: □ Perubahan ini memang cukup signifikan untuk butuh RFC? □ Masalah yang ingin diselesaikan sudah dipahami dengan jelas? □ Sudah diskusi informal dengan minimal satu rekan untuk validasi arah?
SAAT MENULIS RFC: □ Judul jelas dan deskriptif, bisa berdiri sendiri tanpa konteks tambahan □ Latar belakang ditulis untuk audiens yang tidak familiar dengan sistem □ Problem statement terpisah dari solusi, menggunakan data jika memungkinkan □ Tujuan dan non-tujuan keduanya ada dan jelas □ Proposal solusi mencakup high-level design dan flow, bukan detail kode □ Minimal dua alternatif yang dipertimbangkan, dengan alasan penolakan □ Dampak dan risiko ditulis jujur, termasuk failure scenario □ Migration plan ada dan realistic □ Rollback plan ada dan jelas berapa lama waktu rollback □ Open questions ada untuk mengundang masukan
PROSES REVIEW: □ Reviewer yang tepat dilibatkan (bukan hanya yang paling mudah diajak setuju) □ Reviewer diberi waktu cukup (minimal 3–5 hari kerja untuk RFC kompleks) □ Komentar direspon dengan substantif, bukan defensif □ Revisi RFC didokumentasikan (bukan diam-diam diedit tanpa catatan) □ Konsensus dicapai sebelum status berubah ke Accepted
SETELAH IMPLEMENTASI: □ Status RFC diupdate menjadi Implemented □ Perbedaan antara proposal dan implementasi aktual dicatat □ Hasil observasi awal (performance, error rate) ditambahkan □ RFC disimpan di tempat yang mudah ditemukan (Notion, Confluence, repo)
---
## Ringkasan
- RFC adalah alat keputusan, bukan dokumentasi akhir — ia dibuat sebelum implementasi untuk mendapat feedback, bukan setelah untuk memvalidasi apa yang sudah dilakukan.
- Mulai dengan problem, bukan solusi — RFC yang langsung melompat ke proposal tanpa menjelaskan masalahnya dengan jelas membuat reviewer sulit mengevaluasi apakah solusinya tepat.
- Alternatif yang ditolak sama pentingnya dengan solusi yang dipilih — mendokumentasikan mengapa alternatif lain tidak dipilih mencegah ide yang sama diusulkan ulang dan menunjukkan bahwa keputusan dibuat secara sadar.
- Jujur tentang risiko — RFC yang menyembunyikan atau meremehkan risiko tidak membantu siapapun. Reviewer yang baik justru lebih percaya pada RFC yang mengakui ketidakpastian.
- Migration dan rollback plan wajib ada — perubahan yang tidak punya rollback plan adalah taruhan. RFC harus menjelaskan apa yang terjadi jika implementasi ternyata salah.
- RFC formalitas lebih berbahaya dari tidak ada RFC — ia menciptakan ilusi bahwa keputusan sudah divalidasi padahal tidak. Jika RFC dibuat, lakukan dengan sungguh-sungguh.
- Update RFC setelah implementasi — RFC yang berhenti di “Accepted” tanpa catatan hasil adalah setengah dokumen. Tambahkan apa yang berbeda dari proposal dan hasil observasi awal.
- Panjang RFC proporsional dengan kompleksitas — target 2–5 halaman untuk mayoritas RFC. Terlalu panjang sama buruknya dengan terlalu pendek.
- RFC mendistribusikan ownership keputusan — tim yang menggunakan RFC secara konsisten lebih resilient saat anggota berganti karena konteks keputusan tidak tersimpan hanya di kepala satu orang.
- Reviewer yang tepat lebih penting dari banyak reviewer — libatkan orang yang paling terdampak oleh perubahan dan yang memiliki konteks teknis yang relevan, bukan semua orang.
---
← Sebelumnya: Workflow
Berikutnya: Release Document →