Mesin Penjaga Klaim Review di Pesan Commit
Tiga invarian mesin untuk klaim Security-review: tepat satu, posisi trailer, dan substansi dicek terhadap diff.
Ringkasan
Klaim review di pesan commit selama ini cuma perkataan, nggak ada yang ngecek. Jadi repo itu bikin hook commit-msg yang ngetes tiga invarian: baris Security-review: harus tepat satu, posisinya bener, dan klaim tests only dicocokkan sama diff. Hooknya memang bisa di-bypass, tapi tujuannya menaikkan harga kelalaian, bukan nahan penipu.
Sebuah commit menulis Security-review: code+security di trailernya, padahal diff-nya hanya menyentuh satu berkas dokumentasi. Commit lain membawa klaim yang sama dua kali dalam satu pesan. Ada pula yang sama sekali tidak menulis klaim, meski perubahannya menyentuh modul autentikasi. Ketiganya lolos karena klaim review di pesan commit selama ini murni perkataan: tidak ada yang mengecek jumlahnya, posisinya, apalagi isinya. Gerbang baru di repo tersebut mengubah kebiasaan ini menjadi invarian yang diuji mesin, dan pelajarannya relevan untuk repo mana pun yang klaim reviewnya masih berupa teks bebas.
Dari Perkataan ke Invarian
Gerbangnya sebuah skrip bash yang menerima isi pesan commit lewat berkas, lalu menjalankan tiga pemeriksaan. Meletakkannya di hook commit-msg bukan pilihan acak. Dokumentasi Git menjelaskan hook commit-msg menerima "the name of the file that holds the proposed commit log message" dan boleh "refuse the commit after inspecting the message file" [4]. Dengan kata lain, titik pemeriksaan ini persis sebelum commit terbentuk, dan penolakannya menggagalkan commit, bukan sekadar menandai.
Invarian pertama soal jumlah: baris Security-review: harus tepat satu. Nol berarti lupa; dua berarti klaim ganda yang membingungkan dan bisa menyembunyikan kontradiksi dua review berbeda. Invarian kedua soal posisi: trailer harus tepat di atas baris Co-Authored-By dan didahului satu baris kosong. Aturan ini terasa kaku, tapi format yang konsisten membuat trailer itu queryable; skrip audit masa depan bisa memindai riwayat tanpa parser yang rumit.
Invarian ketiga yang paling menarik: klaim "tests only" diverifikasi terhadap diff. Kalau trailer mengklaim hanya test, skrip mencocokkan setiap path di git diff --cached terhadap daftar putih direktori test. Dokumentasi Git mendefinisikan perintah itu sebagai perubahan "between the index and your last commit; what you would be committing if you run git commit without -a option" [5]. Satu path di luar daftar putih, commit ditolak. Ini validasi substansi tanpa NLP: pencocokan path sederhana yang deterministik dan bisa diuji. Skrip bahkan membawa selftest-nya sendiri, jadi logika gerbangnya pun punya test.
Satu keputusan penamaan ikut menentukan daya guna gerbang ini: klaim ditulis sebagai satu baris berawalan tetap di badan pesan, bukan sebagai teks bebas di paragraf deskripsi. Baris yang bentuknya tetap bisa dicacah, dicari, dan dipindahkan antar alat; paragraf bebas hanya bisa dibaca. Seluruh invarian di atas runtuh kalau formatnya dulu saja tidak disepakati.
Pengecualian, Log, dan Batas Gerbang
Commit yang seluruh path-nya non-kode, misalnya hanya dokumentasi, lewat tanpa trailer. Tanpa pengecualian ini, perubahan dokumentasi murni akan memaksa klaim review yang kosong, dan klaim kosong justru menurunkan makna klaim yang sungguhan. Pengecualian menjaga sinyal tetap bernilai.
Dua hal lain saya catat sebagai pelajaran desain. Pertama, lokasi root repo bisa ditimpa lewat environment variable, jadi gerbang yang sama bisa dipanggil dari skrip lain atau selftest tanpa di-hardcode ke satu lokasi; detail kecil yang membedakan skrip sekali-pakai dari alat yang betahan. Kedua, versi pertama gerbang ini terbaca sebagai fondasi yang jujur: baris usage di akhir skrip menyebut subcommand yang belum semuanya terimplementasi, dan dua jalur berkas log audit sudah dideklarasikan di bagian konfigurasi sebelum dipakai. Komit penerusnya yang menambah pemeriksaan berikutnya. Memperluas gerbang jadi aman karena selftest mengunci perilaku yang sudah berlaku, pola yang sama dengan characterization test pada kode produksi.
Batasnya jujur saja: hook Git "can be bypassed with the --no-verify option" [4]. Gerbang ini tidak menahan pihak yang memang berniat melanggar; tujuannya menaikkan harga kelalaian. Kesalahan tanpa niat buruk tertahan di titik commit, sementara audit trail menyimpan siapa mengklaim apa di atas diff yang mana.
Menyalin pola ini ke repo lain tidak perlu menunggu proses resmi yang sempurna. Mulai dari satu invarian paling murah, tepat satu baris klaim, lalu tambahkan posisi dan substansi setelah tim terbiasa. Saya memandang gerbang semacam ini sebagai kontrak tim yang dieksekusi mesin: aturannya dibaca manusia, tapi kepatuhannya tidak lagi bergantung pada ingatan manusia.
Sumber
[4] Git Documentation: githooks, diakses 11 Oktober 2026.
[5] Git Documentation: git-diff, diakses 11 Oktober 2026.