Preflight sadar versi untuk membuka jalan konfigurasi v3
Preflight v3 perlu jalur validasi sendiri tanpa mengubah validator v2 yang dibekukan.
Ringkasan
Preflight v2 sama v3 tuh dipisah biar nggak tabrakan, jadi script sync cuma buat v2 dan script pagesync khusus v3 plus Pages. Validator Pages yang dobel di dua skill dites bareng pake tabel kasus jahat biar hasilnya sama-sama nolak atau nerima. Buat sinkronisasi halaman sekarang ngandelin page id sama verifikasi abis retrieve, bukan marker HTML yang gampang hilang.
Versi konfigurasi harus memilih kontraknya
Pada preflight setelah migrasi v2 ke v3, saya menemukan konfigurasi yang tidak pernah sampai ke mesin Pages. Bukan karena file .pm/plane.json salah tulis, tetapi karena pemeriksaan lama berhenti terlalu awal: sync.py masih memegang validasi v2 dan menolak konfigurasi v3. Commit 122997e merapikan jalur masuknya tanpa mengubah mesin v2 yang sengaja dibekukan. [6]
Sebelum perubahan ini, dua preflight ada di dokumentasi, tetapi pembagian tanggung jawabnya belum cukup tegas. sync.py preflight adalah mesin work-item v2. Ia memeriksa kontrak v2, termasuk ekspektasi yang tidak lagi cocok dengan konfigurasi v3. Kalau dipakai sebagai gerbang universal, konfigurasi v3 berhenti sebelum bagian Pages sempat divalidasi.
Perbaikannya bukan membuat sync.py pura-pura memahami v3. Commit tersebut justru mempertahankan validator lama dan menambahkan pagesync.validate_decisions_block. Helper baru itu memeriksa bagian decisions dengan aturan bentuk yang setara dengan v2, tetapi tanpa persyaratan meetings milik v2. Setelah itu, pagesync.py preflight memeriksa blok Pages. [6]
Pembagian CLI-nya menjadi eksplisit: konfigurasi v2 tetap memakai python3 scripts/sync.py preflight <repo-root>, sedangkan konfigurasi v3 memakai python3 scripts/pagesync.py preflight <repo-root>. Jalur v3 memvalidasi decisions dan Pages. Sebaliknya, preflight Pages pada konfigurasi v2 tetap berhenti dengan kontrak lama. Perubahan versi tidak boleh mengubah arti pemeriksaan untuk repositori yang belum bermigrasi.
pathlib cocok untuk batas ini karena menyediakan objek path dengan semantik yang sesuai untuk sistem operasi tempat program berjalan. [2] Namun abstraksi path tidak menggantikan aturan keamanan: resolve_repo_path(root, rel) tetap harus menolak path absolut dan traversal sebelum file diperlakukan sebagai kandidat Markdown.
Duplikasi validator bukan alasan untuk menebak
Aturan Pages berada di dua skill: plane-init dan plane-doc-sync. Keduanya tidak boleh berbagi import runtime lintas-skill. Duplikasi karena batas itu masih dapat diterima; perilaku yang berbeda tidak.
Commit 037d718 memilih menguji kontraknya, bukan memaksakan pesan error yang sama. Satu tabel kasus adversarial dijalankan melalui kedua validator. Isinya mencakup path traversal, path absolut, file bukan Markdown, direktori di luar .docs, daftar direktori kosong, digest last_sync bukan hex, mapping page_id kosong, dan mapping _template.md. Untuk setiap kasus, yang dibandingkan adalah hasil akhirnya: keduanya menerima atau keduanya menolak. [7]
Ada detail yang lebih penting daripada keseragaman pesan. Resolver path dipanggil sebelum pemeriksaan bentuk nama file. Dengan urutan itu, ../escape.md gagal sebagai traversal, bukan sebagai file yang kebetulan bukan Markdown di bawah .docs. Error precedence seperti ini membantu operator menemukan kelas masalah yang benar.
Pola tersebut sejalan dengan cara pytest mendeskripsikan @pytest.mark.parametrize: satu fungsi uji dapat dijalankan dengan beberapa set argumen dan fixture. [3] Nilai praktisnya bukan sekadar mengurangi baris test, tetapi membuat daftar batas kontrak terlihat. Saat aturan disalin di dua tempat, tabel kasus menjadi alarm drift yang murah.
Verifikasi harus mengikuti bentuk yang disimpan server
Perubahan v3.1 di commit 67f50e0 membawa prinsip yang sama ke sinkronisasi halaman. Desain awal menjadikan marker HTML tersembunyi sebagai identitas. Probe kemudian menemukan bahwa Plane pernah menyimpan bentuk HTML yang sudah dikanonicalisasi dan menghapus marker tersebut. Desain baru memindahkan identitas ke page_id di config dan konvensi nama halaman. Nama dipakai untuk pencarian manusia; mapping yang sudah ada selalu bergabung berdasarkan ID. [8]
Write juga tidak lagi dianggap bukti bahwa server menyimpan payload persis seperti yang dikirim. Setelah update, halaman segera diambil kembali. Nama hasil retrieve harus sesuai konvensi, lalu body yang sudah dikonversi dibandingkan melalui hash normalisasi. Dialek editor yang benar-benar terlihat di fixture boleh ditoleransi; bentuk yang belum pernah diamati tetap gagal keras.
Aturan ini punya dasar operasional yang jelas. Dokumentasi API Plane menyatakan bahwa HTML disanitasi, diubah ke format dokumen editor, lalu seluruh body halaman diganti ketika update. [4] Karena itu, verifikasi setelah retrieve lebih kuat daripada hanya memeriksa payload request. HTMLParser Python menyediakan basis untuk menangani tag pembuka, tag penutup, teks, komentar, dan markup lain, tetapi parser tidak boleh dijadikan alasan untuk menerima bentuk editor yang belum dibuktikan. [5]
Saya memilih desain ini karena batas perubahannya terlihat jelas: validator v2 tetap utuh, v3 mendapat pintu masuk sendiri, dan dua salinan aturan Pages dipaksa menyepakati hasil pada input yang berbahaya. Preflight menjadi pagar yang membaca versi konfigurasi sebelum memilih aturan, bukan palu lama yang memukul semua bentuk dengan kontrak yang sama.