Langsung ke konten

← Kembali ke Perpustakaan

L4 · 9 Okt 2026

Spec-driven development bersama AI coding agent

  • spec-driven-development
  • ai-coding-agents
  • github-spec-kit
  • code-review
  • case-study

Saya membangun portal manajemen vendor dalam sekitar enam minggu, sebagai satu-satunya engineer di repositori itu. Sebagian besar kode ditulis AI coding agent. Semua 179 pull request saya buka dan saya merge sendiri.

Itu menjelaskan bagaimana pekerjaan ini selesai, sekaligus bagian paling lemah dari prosesnya: tidak ada reviewer manusia kedua.

Proyeknya berjalan dari 21 Agustus sampai 4 Oktober 2026 untuk sebuah unit bisnis di grup. Portal ini menangani onboarding vendor, purchase order, penerimaan barang, invoice dengan verifikasi pajak, dan approval bertingkat. Stack-nya FastAPI, PostgreSQL, dan Next.js, di-deploy ke Azure App Service. Di akhir periode, ada 51 spec bernomor, 21 domain backend, dan 110 migrasi Alembic.

Produknya tidak punya fitur AI. Saya memakai GitHub Copilot dan Claude untuk implementasi. Saya yang menulis spec, merancang arsitektur, me-review PR, dan memutuskan apa yang masuk. Pembagian kerja ini bergantung pada kejelasan pekerjaan sebelum agent mulai menulis kode. Beberapa bug serius tetap lolos.

Kenapa spec dulu, baru kode

Agent bisa cepat menulis approval engine yang kelihatan masuk akal. Tapi apakah engine itu sesuai dengan proses bisnis? Saya yang harus menentukan arti "benar" dan menyiapkan cara untuk mengeceknya.

Saat sebagian besar pengetikan dilakukan agent, justru bagian itu yang menjadi bottleneck. Riwayat chat panjang bukan tempat yang cocok untuk menyimpan keputusan tersebut.

Commit pertama saya berisi blueprint, bukan kode. Saya menulisnya dengan GitHub Spec Kit: lima belas spec untuk domain, identitas, data, dan deployment, serta constitution berisi aturan yang wajib diikuti setiap agent. Spec fitur berikutnya masing-masing punya ID task, acceptance criteria, dan business rule. Di akhir proyek, repositori sudah merujuk ribuan ID.

Selama masih berupa dokumen, desain lebih mudah diubah. Pada hari kedua, saya mengganti Cosmos DB dengan PostgreSQL di blueprint karena domainnya membutuhkan integritas relasional dan constraint. Alasannya saya catat di decision record.

Pada hari keempat, adversarial consistency review menemukan 24 defect di seluruh spec, kebanyakan berupa kontradiksi antar spec. Saya memperbaikinya sebelum ada agent yang membangun di atasnya. Dua perubahan itu cukup dengan satu siang mengedit dokumen, bukan migrasi.

Alur kerjanya

Setiap fitur melewati jalur yang sama:

spec bernomor (ID task, AC, business rule)
  -> constitution + file konvensi agent
  -> agent mengerjakan di worktree sendiri
  -> pull request, CI gate
  -> saya review, saya merge

Constitution dan file konvensi menyimpan aturan yang tidak boleh ditafsirkan ulang oleh agent. Misalnya, two-boundary rule: Next.js hanya menangani presentasi dan backend-for-frontend, sementara seluruh business logic ada di FastAPI. Permission wajib diturunkan ulang dari database pada setiap request, tidak boleh dipercaya dari client.

Untuk tahap besar, saya menjalankan beberapa agent secara paralel di git worktree terpisah. Branch mereka lalu saya gabungkan lewat PR fan-in. CI gate membantu menjaga pekerjaan itu tetap bisa di-review.

Selain typecheck, lint, build, bundle-size budget, dan ruff, CI mengecek keterkaitan pekerjaan dengan ID spec. Ada juga drift check untuk TypeScript API client yang di-generate, secret scan, architecture test, dan extended tier dengan service PostgreSQL 16 sungguhan. Deploy hanya berjalan setelah CI hijau.

Gate memang menolak pekerjaan. Dari run CI terbaru yang tercatat sejak 1 September, 140 dari 488 gagal. Saya tidak mengklasifikasikan penyebabnya, jadi tidak bisa memisahkan kesalahan agent, kesalahan saya, dan gangguan infrastruktur. Angka itu tidak menjawab siapa yang salah di mana.

Saat alur kerja dipusatkan ke purchase order

Model awal berpusat pada dokumen penerimaan barang. Proses bisnis yang direvisi, disetujui pada 11 September, memindahkan pusatnya ke purchase order.

Perubahannya berarti satu PO workspace bersama untuk vendor dan staf internal, dokumen diganti di tempat, serta referensi disimpan secara persis, bukan lagi "dokumen terbaru yang menang". Pada 25 September, product owner juga mengarahkan penghapusan approval matrix yang bisa dikonfigurasi. Rute approval kemudian ditentukan di kode.

Saya menulis spec bernomor baru untuk perubahan tersebut. Pivot ke purchase order masuk antara 9 hingga 16 September. Penghapusan approval matrix memakai migrasi expand and contract agar data lama tetap bisa dibaca saat routing baru mengambil alih.

Bagi saya, manfaatnya terasa saat bisa membaca diff dokumen sebelum diff kode. Acceptance criteria yang tergantikan terlihat jelas, task untuk agent bisa dibatasi sesuai spec baru, dan ledger guard menandai pekerjaan yang tidak punya requirement.

Itu penalaran saya, bukan penghematan waktu yang sudah diukur. Saya tidak punya pembanding.

Ada biaya cleanup juga. Spec yang tergantikan meninggalkan kode yang tidak lagi terjangkau. Saya baru menghapusnya dalam putaran khusus test debt dan dead code pada 4 Oktober. Saya sudah memberi tahu agent apa yang harus dibangun, tetapi belum memberi tahu apa yang harus dihapus.

Yang tetap lolos

Repositori tidak mencatat apakah tiap baris ditulis oleh saya atau agent. Sebagian besar kode ditulis agent, dan semuanya saya setujui. Kegagalan berikut tetap tanggung jawab saya.

CI hijau karena test-nya tidak berjalan

Integration tier membutuhkan URL database. Kalau URL tidak ada, pytest melewati tier tersebut dan CI tetap hijau.

Saat suite lengkap dijalankan terhadap PostgreSQL sungguhan, muncul 45 failure dan 301 error, dengan 5 defect nyata di antaranya. Saya memperbaiki kelimanya, membuat kebutuhan database eksplisit, dan mengoreksi klaim tentang apa yang dicek CI.

Tier yang di-skip terlihat sama dengan tier yang lolos. Agent yang mengandalkan feedback itu tidak punya cara untuk membedakannya.

Cookie lolos test, tetapi terlalu besar untuk browser

Login memakai sealed HttpOnly cookie yang membungkus token bertanda tangan. Token itu membawa permission user.

Dengan 58 permission grant, cookie mencapai 4.234 sampai 4.491 byte, melewati batas sekitar 4 KB yang diterima browser. Login staf mengembalikan 500. Fixture test-nya memakai signature palsu sepanjang 9 karakter, jadi masalah ukuran ini tidak terlihat.

Saya mencoba chunking cookie, lalu kompresi yang ternyata tidak tersedia di edge runtime. Keduanya bukan jawaban untuk masalah desainnya. Backend sudah menurunkan ulang permission pada setiap request; token cukup menyimpan kode yang dibutuhkan UI untuk gating. Setelah dibatasi ke kode tersebut, ukurannya menjadi 2.083 byte.

Browser mengecek sesi sebelum transaksi commit

Setelah login lewat Entra ID, callback mengembalikan 200. Pengecekan sesi berikutnya malah mendapat 401: "session does not exist".

Dari koneksi database kedua, saya bisa melihat bahwa barisnya ada, hanya terlambat. Dependency FastAPI yang memegang transaksi melakukan commit saat teardown. Pada versi yang saya pin, teardown berjalan setelah response terkirim. Browser lebih cepat daripada commit.

Urutan ini berlaku untuk semua endpoint yang menulis data, bukan hanya login. Perbaikannya melakukan commit sebelum mengirim response dan gagal secara eksplisit kalau langkah itu tidak ada.

Ketiga masalah ini bukan celah di spec. Sumbernya konfigurasi CI, batas browser, dan lifecycle framework, detail yang tidak dijelaskan oleh spec. Agent mengikuti test yang saya berikan. Saat environment test-nya salah, agent ikut mewarisi kesalahannya.

Yang akan saya pertahankan dan ubah

Saya tetap akan memakai spec bernomor dengan ID task, acceptance criteria, dan business rule, lalu me-review-nya secara adversarial sebelum coding. Saya juga akan mempertahankan satu constitution dan file konvensi untuk semua agent, aturan arsitektur yang dijaga test, CI untuk traceability dan kontrak, serta merge gate yang dipegang manusia.

Tetapi untuk autentikasi, approval, dan alur terkait pembayaran, saya tidak mau menjadi satu-satunya reviewer lagi. Bagian itu membutuhkan reviewer manusia kedua.

Perubahan lainnya konkret: CI fail-closed sejak awal, sehingga tier yang di-skip membuat build gagal; fixture yang bentuk dan ukurannya mirip production; serta smoke test di environment ter-deploy dengan identity provider sungguhan sebelum login dianggap selesai. Setiap spec yang menggantikan pekerjaan lama juga perlu menyertakan penghapusan kode yang sudah tidak dipakai.

Pengukurannya pun perlu saya perbaiki. Saya tidak mencatat waktu per spec, defect berdasarkan asalnya, atau baseline tanpa agent. Jadi proyek ini tidak memberi dasar untuk klaim produktivitas. Lain kali, saya akan mencatatnya sejak spec pertama.

Sekarang saya memakai GitHub Spec Kit dengan constitution berversi di setidaknya sembilan repositori. Yang akan saya bawa ke proyek berikutnya bukan sekadar menyerahkan coding ke agent. Pekerjaannya harus cukup jelas untuk di-review, dan saya harus memastikan check benar-benar berjalan sebelum percaya pada hasil hijau.