Validator Raib, CI Tetap Hijau
Sync mirror menghapus skrip validasi dan CI tetap hijau. Tiga kelas kegagalan validator plus dua pagar murah berupa anchor wajib dan checksum beku.
Ringkasan
Validator bisa hilang diam-diam tapi pipeline tetap hijau, padahal hijau harusnya berarti sehat. Ada tiga kelas kegagalannya: validator hilang, rusak senyap, atau rapuh gara-gara perilaku shell yang beda-beda. Solusinya murah: wajibkan anchor di terjemahan dan freeze checksum selftest, jadi kalau validator nggak cocok pipeline langsung merah.
Pagi itu saya buka dashboard CI dan semua centangnya hijau. Iseng, saya cek folder scripts, dan skrip check-close-actions-drift.sh raib. Sync git mirror diam-diam menghapusnya. Yang bikin kesal, pipeline tetap lolos karena nggak ada satu step pun yang mengecek apakah si pengecek masih ada. Alat pemantau hilang, tapi laporan kesehatan tetap bersih.
Tebakan pertama saya salah. Saya mengira hijau berarti sehat. Kenyataannya, suite tetap hijau justru karena validatornya lenyap. Setelah membongkar diff commit perbaikannya, saya menemukan bukan satu tapi tiga kelas kegagalan validator sekaligus, dan ketiganya bekerja senyap.
Tiga kelas kegagalan validator
Kelas pertama paling jelas: validator hilang. Nggak ada mekanisme yang memverifikasi keberadaan alat verifikasi itu sendiri, jadi penghapusannya lolos tanpa jejak di dashboard.
Kelas kedua lebih halus: validator rusak diam-diam. Ada bug di mana iterator baris _iter_rows terbungkus ganda, dan akibatnya aturan unclosed-action (R105) nggak pernah menyala. Padahal ada berkas terjemahan yang benar kehilangan penutup aksinya. Ini tipe kegagalan favorit saya untuk dibenci: alatnya ada, laporannya bilang sehat, padahal dia bisu.
Kelas ketiga: validator rapuh. Fixture selftest sempat flake karena substitusi escaped-brace di konteks fungsi bash pada bash 5.2.37. String substitution yang mengandalkan perilaku parsing shell bikin hasil test beda antar lingkungan. Perbaikannya geser ke mutasi berbasis path lewat helper mutate, yang lebih deterministik karena nggak bersandar pada keanehan versi shell.
Drift itu kondisi normal, bukan insiden
Setelah ketiga kelas ini kelihatan, satu kesimpulan kecil saya tarik: salinan paralel itu normal. Di workflow terdistribusi, tiap pihak bekerja dengan tempo sendiri dan developer kedua wajib merge sebelum push supaya nggak menimpa kerja developer pertama. Sinkronisasi memang manual, jadi drift selalu mengintai [3].
Dokumen terjemahan punya pola serupa. Sphinx memperlakukan katalog pesan sebagai bahan yang dikompilasi ke direktori locale, misalnya ./locale/es/LC_MESSAGES/usage.mo, dan hasil build itu hidup di siklusnya sendiri, terpisah dari sumber aslinya [2]. Setiap salinan yang punya siklus hidup sendiri butuh alarm, bukan sekadar harapan bahwa semuanya akan tetap sinkron.
Dua pagar murah
Pagar pertama: anchor wajib. Aturan baru translated-anchor-missing (R89) membuat section hasil terjemahan tanpa anchor_sections langsung gagal validasi. Nggak ada lagi section terjemahan yang berdiri sendiri tanpa jejak ke bagian sumbernya. Saat dokumen sumber berubah, anchor yang menggantung itu otomatis terlihat, bukan ditemukan berbulan-bulan kemudian oleh pembaca.
Pagar kedua: checksum beku. Selftest di-freeze ulang dengan nilai eb512923, dan perubahan apa pun pada skrip pengujian membuat hash nggak cocok. Perlu diingat batasannya: checksum andal mendeteksi korupsi tak sengaja, karena peluang dua berkas memiliki digest identik sangat kecil, tapi dia bukan pelindung dari manipulasi disengaja [4]. Untuk alarm drift internal yang nggak menghadapi penyerang, itu sudah lebih dari cukup.
Sementara itu, pembacaan konstanta seperti STATE_ACTIONS dan CLOSE_ACTIONS dari source Python tetap lewat ast.literal_eval, karena dia hanya mengevaluasi struktur literal: string, bytes, number, tuple, list, dict, set, boolean, None, dan Ellipsis [1]. Validasi yang membaca kode jadi nggak membuka celah eksekusi kode tersembunyi.
Dua pagar ini murah karena sama sekali nggak menambah infrastruktur. Yang berubah cuma kontrak: kalau validatornya hilang atau hash-nya nggak cocok, pipeline wajib merah. Hijau harus berarti sesuatu.