Claude Code untuk kegagalan CI: minta agar mengutip output yang gagal, sarankan perbaikan sekecil mungkin, dan tambahkan tes regresi agar tidak terulang.

Kegagalan CI biasanya tidak misterius. Log memberitahu di mana proses berhenti, perintah apa yang gagal, dan pesan error. Run yang bagus menyertakan stack trace, error compiler dengan file dan nomor baris, atau laporan test yang menunjukkan assertion mana yang gagal. Kadang Anda bahkan mendapatkan petunjuk gaya diff seperti "expected X, got Y" atau langkah yang jelas gagal seperti "lint", "build", atau "migrate database".
Masalah sebenarnya adalah orang (dan AI) sering menganggap log sebagai noise. Jika Anda menempelkan log panjang dan meminta "sebuah perbaikan", banyak model langsung lompat ke penjelasan yang akrab alih-alih membaca baris bermakna terakhir. Tebakan jadi lebih buruk ketika error terlihat umum ("module not found", "timeout", "permission denied"). Anda berakhir dengan rewrite besar, dependency baru, atau jawaban "coba update semuanya" yang tidak cocok dengan kegagalan sebenarnya.
Tujuannya bukan "membuatnya lulus dengan cara apa pun". Lebih sederhana:
Dalam praktiknya, "perbaikan terkecil" biasanya salah satu dari ini: perubahan kode beberapa baris di satu tempat, import yang hilang atau path yang salah, nilai konfigurasi yang jelas salah untuk environment CI, atau mengembalikan perubahan yang tidak sengaja merusak daripada merancang ulang kode.
Tes tindak lanjut juga penting. Lulus CI sekali bukan sama dengan mencegah pengulangan. Jika kegagalan berasal dari edge case (input null, zona waktu, pembulatan, izin), tambahkan tes regresi yang gagal sebelum perbaikan dan lulus setelahnya. Itu mengubah penyelamatan sekali jadi sebuah pagar pengaman.
Kebanyakan perbaikan buruk dimulai dari konteks yang hilang. Jika Anda hanya menempelkan baris merah terakhir, model harus menebak apa yang terjadi sebelumnya, dan tebakan sering berubah menjadi rewrite.
Tujuannya adalah memberikan detail yang cukup sehingga orang bisa mengikuti kegagalan dari error nyata pertama sampai akhir, lalu mengubah sesedikit mungkin.
Salin ini ke dalam pesan Anda (verbatim bila memungkinkan):
go test ./..., npm test, flutter test, golangci-lint run).Tambahkan batasan dengan kata-kata biasa. Jika Anda menginginkan perbaikan kecil, katakan: tidak refactor, tidak ubah perilaku kecuali perlu, batasi patch ke area yang gagal.
Contoh sederhana: CI gagal di langkah lint setelah bump dependency. Tempelkan output lint mulai dari peringatan pertama, sertakan perintah yang digunakan CI, dan sebutkan perubahan versi paket tunggal. Itu cukup untuk menyarankan tweak konfigurasi satu baris atau perubahan kode kecil, alih-alih memformat ulang setengah repo.
Jika Anda menginginkan sesuatu yang bisa disalin-tempel, struktur ini biasanya cukup:
CI command:
Failing output (full):
Recent changes:
Constraints (smallest fix, no refactor):
Flaky? (runs attached):
Ketika sebuah model meleset pada pemutusan CI, biasanya karena prompt Anda membiarkannya menebak. Tugas Anda adalah membuatnya menunjukkan cara berpikirnya menggunakan output CI yang tepat, lalu berkomitmen ke perubahan terkecil yang bisa membuat job lulus.
Minta bukti dan rencana kecil. Prompt yang bagus memaksa lima hal:
Ketidakpastian boleh ada. Ketidakpastian tersembunyi yang membuang waktu.
Tempel ini di bagian atas pertanyaan CI Anda:
Use ONLY the evidence in the CI output below.
1) Quote the exact failing lines you are using.
2) Give ONE sentence: the most likely cause.
3) Propose the smallest fix: 1-3 edits, with file paths.
4) Do NOT do formatting/renames/refactors or "cleanup".
5) List uncertainties + the one extra detail that would confirm the diagnosis.
Jika log mengatakan "expected 200, got 500" plus stack trace ke user_service.go:142, struktur ini mendorong respons ke fungsi itu dan perubahan penjaga kecil atau penanganan error, bukan redesain endpoint.
Kemenangan tercepat datang dari prompt yang memaksa pengutipan log, tetap di dalam batasan, dan berhenti saat sesuatu hilang.
You are helping me fix a CI failure.
Repo context (short):
- Language/framework:
- Test/build command that failed: <PASTE THE EXACT COMMAND>
- CI environment (OS, Node/Go/Python versions, etc.):
Failing output (verbatim, include the first error and 20 lines above it):
<PASTE LOG>
Constraints:
- Propose the smallest possible code change that makes CI pass.
- Do NOT rewrite/refactor unrelated code.
- Do NOT touch files you do not need for the fix.
- If behavior changes, make it explicit and justify why it is correct.
Stop rule (no guessing):
- If the log is incomplete or you need more info (missing stack trace, config, versions, failing test name), STOP and ask only the minimum questions needed.
Your response format (follow exactly):
1) Evidence: Quote the exact log lines that matter.
2) Hypothesis: Explain the most likely cause in 2-4 sentences.
3) Smallest fix: Describe the minimal change and why it addresses the evidence.
4) Patch: Provide a unified diff.
5) Follow-up: Tell me the exact command(s) to rerun locally to confirm.
Then, write ONE regression test (or tweak an existing one) that would fail before this fix and pass after it, to prevent the same failure class.
- Keep the test focused. No broad test suites.
- If a test is not feasible, explain why and propose the next-best guardrail (lint rule, type check, assertion).
Dua detail yang mengurangi bolak-balik:
Cara tercepat kehilangan waktu adalah menerima perubahan “cleanup” yang memodifikasi lima hal sekaligus. Definisikan "minimal" sejak awal: diff terkecil yang membuat job yang gagal lulus, dengan risiko terendah dan cara verifikasi tercepat.
Aturan sederhana bekerja baik: perbaiki gejala dulu, lalu putuskan apakah refactor lebih luas layak. Jika log menunjuk ke satu file, satu fungsi, satu import yang hilang, atau satu edge case, arahkan ke sana. Hindari perubahan "sambil di sini".
Jika Anda benar-benar perlu alternatif, minta dua dan hanya dua: "perbaikan minimal paling aman" vs "perbaikan minimal tercepat." Anda ingin tradeoff, bukan menu.
Juga minta verifikasi lokal yang cocok dengan CI. Minta perintah yang sama yang dijalankan pipeline (atau yang paling mirip), sehingga Anda bisa konfirmasi dalam beberapa menit:
# run the same unit test target CI runs
make test
# or the exact script used in CI
npm test
Jika respons menyarankan perubahan besar, dorong kembali dengan: "Tunjukkan patch terkecil yang memperbaiki assertion yang gagal, tanpa formatting atau rename yang tidak terkait."
Perbaikan tanpa tes adalah taruhan bahwa Anda tidak akan menemui masalah yang sama lagi. Selalu minta tes regresi tindak lanjut yang gagal pada branch main saat ini dan lulus setelah perbaikan.
Spesifik tentang apa yang “baik”:
Polanya berguna: minta empat hal: di mana meletakkan test, nama filenya, perilaku yang diuji, dan catatan singkat mengapa itu mencegah regresi.
Fragmen siap-salin tambahan:
Contoh: CI menunjukkan panic saat handler API menerima ID string kosong. Jangan minta "tes untuk baris ini." Minta tes yang mencakup ID tidak valid (kosong, spasi, format salah). Perbaikan terkecil mungkin guard clause yang mengembalikan 400. Tes tindak lanjut harus mengasert perilaku untuk banyak input tidak valid, sehingga jika seseorang merefaktor parsing, CI langsung gagal.
Jika proyek Anda sudah punya konvensi test, sebutkan. Jika tidak, minta model mengikuti tes di paket atau folder yang sama, dan buat tes baru yang minimal dan mudah dibaca.
Tempel bagian log CI yang mencakup error dan 20–40 baris di atasnya. Juga tempel perintah gagal persis yang dijalankan CI dan detail environment kunci (OS, versi runtime, flag penting).
Lalu minta untuk menyatakan kembali apa yang gagal dengan bahasa biasa dan tunjukkan baris di output yang membuktikannya. Jika ia tidak bisa mengutip log, ia belum benar-benar membacanya.
Minta perubahan terkecil yang membuat perintah gagal lulus. Tolak refactor. Sebelum menerapkan, minta ia daftar:
Terapkan patch dan jalankan perintah yang gagal persis secara lokal (atau di job CI yang sama jika itu satu-satunya pilihan). Kalau masih gagal, tempelkan hanya output gagal baru dan ulangi. Menjaga konteks kecil membantu respons tetap fokus.
Setelah hijau, tambahkan satu tes tindak lanjut yang akan gagal sebelum patch dan lulus setelahnya. Tetap fokus: satu tes, satu alasan.
Jalankan lagi perintah dengan tes baru untuk memastikan Anda tidak hanya menutup suara error.
Minta pesan commit singkat dan deskripsi PR yang mencakup apa yang gagal, apa yang berubah, bagaimana Anda memverifikasinya, dan tes yang mencegah pengulangan. Reviewer bergerak lebih cepat ketika alasan dijelaskan.
Kegagalan umum: semuanya bekerja di lokal, lalu perubahan kecil membuat test gagal di runner CI. Berikut contoh sederhana dari API Go di mana handler mulai menerima nilai date-only (2026-01-09) tetapi kode masih mem-parsing hanya timestamp RFC3339 penuh.
Ini jenis snippet yang harus Anda tempel (jaga singkat, tapi sertakan baris error):
--- FAIL: TestCreateInvoice_DueDate (0.01s)
invoice_test.go:48: expected 201, got 400
invoice_test.go:49: response: {"error":"invalid due_date: parsing time \"2026-01-09\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"\" as \"T\""}
FAIL
exit status 1
FAIL app/api 0.243s
Sekarang gunakan prompt yang memaksa bukti, perbaikan minimal, dan tes:
You are fixing a CI failure. You MUST use the log to justify every claim.
Context:
- Language: Go
- Failing test: TestCreateInvoice_DueDate
- Log snippet:
<PASTE LOG>
Task:
1) Quote the exact failing line(s) from the log and explain the root cause in 1-2 sentences.
2) Propose the smallest possible code change (one function, one file) to accept both RFC3339 and YYYY-MM-DD.
3) Show the exact patch.
4) Add one regression test that fails before the fix and passes after.
Return your answer with headings: Evidence, Minimal Fix, Patch, Regression Test.
Respons yang bagus akan menunjuk ke mismatch layout parsing, lalu membuat perubahan kecil di satu fungsi (misal parseDueDate di invoice.go) untuk mencoba RFC3339 terlebih dahulu dan fallback ke 2006-01-02. Bukan refactor, bukan paket baru.
Tes regresi adalah pagar pengaman: kirim due_date: "2026-01-09" dan harapkan 201. Jika nanti seseorang "membersihkan" parsing dan menghapus fallback, CI akan langsung kembali gagal dengan kelas masalah yang sama.
Cara tercepat kehilangan satu jam adalah memberi tampilan masalah yang terpotong. Log CI berisik, tapi bagian yang berguna sering 20 baris di atas error terakhir.
Satu jebakan adalah hanya menempel baris merah terakhir (misal, "exit 1") sementara menyembunyikan penyebab sebenarnya lebih awal (env var yang hilang, snapshot yang gagal, atau test pertama yang crash). Solusi: sertakan perintah gagal plus jendela log di mana error nyata pertama muncul.
Kebiasaan buruk lain: membiarkan model "membersihkan" sepanjang jalan. Formatting ekstra, bump dependency, atau refactor membuat lebih sulit meninjau dan lebih mudah merusak hal lain. Solusi: kunci scope ke perubahan terkecil dan tolak hal yang tidak relevan.
Beberapa pola yang perlu diwaspadai:
Jika Anda curiga flaky, jangan menutupinya dengan retries. Hilangkan randomness (waktu tetap, seed RNG, direktori temp terisolasi) supaya sinyal menjadi jelas.
Sebelum push, lakukan pengecekan singkat. Tujuannya memastikan perubahan nyata, minimal, dan dapat direproduksi, bukan sekedar lulus karena keberuntungan.
Akhirnya, jalankan set yang sedikit lebih luas daripada job yang gagal (misal, lint plus unit tests). Perangkap umum: perbaikan yang lulus target asli tapi merusak target lain.
Jika Anda ingin ini menghemat waktu tiap minggu, perlakukan prompt dan struktur respons seperti proses tim. Tujuannya adalah input yang bisa diulang, output yang bisa diulang, dan lebih sedikit "perbaikan misterius" yang merusak hal lain.
Jadikan prompt terbaik Anda snippet bersama dan pin di chat tim. Tujuan: semua orang menggunakan format yang sama sehingga reviewer tahu di mana melihat.
Siklus kebiasaan ringan yang bekerja di banyak tim:
Jika Anda suka alur chat-first untuk membangun dan iterasi aplikasi, Anda bisa menjalankan loop perbaikan-dan-tes yang sama di Koder.ai, gunakan snapshot saat bereksperimen, dan ekspor kode ketika siap untuk merge kembali ke repo biasa.
Mulailah dari error nyata pertama, bukan exit 1 terakhir.
Minta bukti bahwa ia membaca log.
Gunakan batasan seperti:
Default ke patch terkecil yang membuat langkah yang gagal berhasil.
Biasanya berarti:
Hindari perubahan “bersih-bersih” sampai CI hijau lagi.
Tempelkan konteks yang cukup untuk mereproduksi kegagalan, bukan hanya baris merah terakhir.
Sertakan:
Ya—nyatakan batasan dengan jelas dan ulangi.
Contoh batasan:
Ini menjaga respons tetap fokus dan mudah ditinjau.
Perbaiki kegagalan nyata yang paling awal terlebih dulu.
Kalau ragu, minta model mengidentifikasi langkah pertama yang gagal di log dan fokus di situ.
Anggap flaky sebagai sinyal untuk menghilangkan randomness, bukan menambahkan retry.
Stabilisator umum:
Setelah deterministik, "smallest fix" biasanya jelas.
Minta perintah yang persis dijalankan CI, lalu jalankan itu secara lokal.
Jika reproduksi lokal sulit, minta repro minimal di dalam repo (satu test/target) yang memicu error sama.
Tulislah satu tes regresi fokus yang gagal sebelum perbaikan dan lulus setelahnya.
Target yang bagus termasuk:
Kalau itu kegagalan lint/build, “tes” yang setara mungkin memperketat rule lint atau menambah check yang mencegah kesalahan yang sama.
Gunakan snapshot/rollback agar eksperimen reversible.
Loop praktis:
Jika Anda memakai Koder.ai, snapshot membantu iterasi cepat tanpa mencampur edit eksperimen ke patch final yang akan diekspor.
go test ./...npm testflutter test