Sebuah patch agen hanya dapat menyitasi pengikatan beku setelah rekam jejak pengikat ditutup. Rekam jejak tersebut menghubungkan tiga artefak yang dihitung dari pohon permintaan tarik: ID cakupan properti, digest fixture, dan hash contoh kontra yang disimpan. Baris kegagalan yang berulang dalam log bukan salah satu dari artefak tersebut. Jika ada field yang hilang, atau jika field tersebut disalin dari pohon lain, sitasi akan ditolak dan patch tetap terbuka. Ini adalah gerbang tinjauan yang diusulkan, bukan pelaksanaan yang diukur. Tidak ada tingkat lulus, kuota, atau ukuran runner yang diklaim di bawah ini. Perintah-perintah dan pengecek ini adalah contoh yang belum dieksekusi. Arahkan mereka ke jalur Anda sendiri sebelum Anda menganggap kode keluar sebagai bukti.
Prinsip Kesesuaian Artefak dan Cakupan
Apa yang harus sesuai. Cakupan properti menamai predikat dan domain masukan yang patch mengklaim memegang. Digest fixture menghash sumber generator, file cakupan, dan kunci benih. Contoh kontra yang disimpan adalah masukan yang gagal disimpan sebagai byte, bukan direkonstruksi dari stdout. Ketiga hal tersebut harus menamai cakupan yang sama. Digest dari generator minggu lalu tidak dapat mengotorisasi pengikatan beku pada predikat minggu ini. Contoh kontra yang tidak hash ke sitasi tidak dapat mengotorisasinya juga.
Membaca Cakupan Properti dari Perbedaan Patch
Langkah 1: Baca cakupan dari perbedaan. Mulailah dengan patch. Daftarkan jalur properti dan fixture sebelum Anda membuka log CI. Log hanya dapat mendeskripsikan jalannya yang sudah terjadi. Gerbang membutuhkan file yang jalannya seharusnya menggunakan. git fetch origin main git diff --name-only origin/main...HEAD -- tests/properties tests/fixtures tests/bindings Setiap file properti yang berubah membutuhkan dokumen cakupan dalam perbedaan yang sama. Dokumen tersebut adalah data. Jangan minta gerbang untuk memulihkan domain dari docstring. scope_id : order_total.non_negative predikat : tests/properties/order_total.py:test_total_non_negative domain : mata_uang : [ USD , EUR ] qty : { min : 1 , max : 20 } generator : tests/fixtures/gen_orders.py versi_schema : 3 Tolak patch ketika predikat atau domain berubah dan file cakupan tidak berubah. Pembagian itu adalah cara pengikatan beku menjaga ID lama sementara pengecekan di bawahnya bergerak.
Menghash Byte Generator Fixture
Langkah 2: Hash byte generator, bukan output yang dihasilkan. Menghash JSON yang dihasilkan lebih lemah daripada menghash generator. Sebuah agen dapat membiarkan file output hari kemarin tidak berubah dan masih mengubah skrip yang akan berjalan pada benih berikutnya. Digest harus mencakup skrip. python - << ' PY ' import hashlib, pathlib parts = [ "tests/fixtures/gen_orders.py", "tests/properties/order_total.scope.yaml", "tests/fixtures/seeds.lock", ] h = hashlib.sha256() for p in parts: blob = pathlib.Path(p).read_bytes() h.update(p.encode()) h.update(bytes([0])) h.update(blob) print(h.hexdigest()) PY Simpan hex hanya setelah Langkah 3 menyimpan contoh kontra. File digest dengan hash contoh kontra null adalah rekam jejak terbuka. Jangan komitnya, dan jangan biarkan file beku menunjuk padanya. Sertakan versi schema dalam file cakupan yang dihash sehingga perubahan format mengubah digest. Dua runner dapat berbeda setelah perubahan parser yang diam-diam sementara hex lama tetap hijau. Jika Anda meningkatkan versi, hitung ulang digest dalam commit yang sama.
Penyimpanan Sampel Contoh Kontra Terbatas
Langkah 3: Simpan satu contoh kontra dari jalannya yang terbatas. Jalankan pengecekan properti dengan benih dan domain dari file cakupan. Batasi jumlah contoh. Pencarian yang tidak terbatas membuat masukan yang disimpan tidak dapat direproduksi bahkan ketika benih tetap, karena kondisi berhenti bergerak. PROPERTY_SCOPE = tests/properties/order_total.scope.yaml COUNTEREXAMPLE_OUT = tests/bindings/order_total.non_negative.cex.json python -m tools.property_run --seed 17 --max-examples 200 Pada kegagalan, runner yang diusulkan menulis satu objek JSON. Jalannya yang lulus tidak menulis apa-apa. Kandidat beku tidak dapat lahir dari lulus. { "scope_id" : "order_total.non_negative" , "seed" : 17 , "example_index" : 44 , "input" : { "currency" : "EUR" , "qty" : 3 , "unit_cents" : -1 }, "predicate_result" : "fail" , "shrink_steps" : 6 } Kemudian hash file tersebut. Sitasi akan membawa hex ini, bukan indeks contoh. Indeks bergerak ketika generator berubah. Byte tidak. python -c "import hashlib, pathlib; p=pathlib.Path('tests/bindings/order_total.non_negative.cex.json'); print(hashlib.sha256(p.read_bytes()).hexdigest())" Jika runner tidak dapat mengurangi menjadi satu masukan, hentikan alur kerja. Balapan multiproses dan fixture jaringan langsung tidak termasuk dalam rekam jejak ini. Karantina mereka di bawah kebijakan yang berbeda.
Klasifikasi pada Worktree Bersih
Langkah 4: Klasifikasikan file tersebut pada worktree yang bersih. Salin contoh kontra dan cakupan ke worktree kedua pada commit yang sama. Evalusi predikat pada masukan tersebut saja. Jangan jalankan generator lagi. Sampel baru dapat melewatkan kasus yang disimpan dan membuat pengecekan yang tidak stabil terlihat tertutup. git worktree add --detach /tmp/bind-check HEAD cp tests/bindings/order_total.non_negative.cex.json /tmp/bind-check/tests/bindings/ python -m tools.property_eval --scope tests/properties/order_total.scope.yaml --case tests/bindings/order_total.non_negative.cex.json Beri label hasil worktree class_local. Lingkungan kedua yang Anda kontrol dapat menyediakan class_isolated. Kedua label harus mendeskripsikan file yang disalin, bukan sampel yang baru dihasilkan. Perbedaan antara label akan membiarkan rekam jejak terbuka. Perbaiki fixture, predikat, atau gambar runner sebelum seseorang menulis sitasi. Jangan menutupi perpecahan dengan string alasan beku yang lebih luas.
Penyusunan Sitasi Berbasis Data Triple
Langkah 5: Tulis sitasi dari triple yang tertutup. Sitasi adalah data. Ini menamai triple dan dua label kelas. Ini tidak menamai uji yang patch baru saja buat, dan tidak menempelkan potongan log sebagai gantinya. { "scope_id" : "order_total.non_negative" , "fixture_digest" : "<sha256 dari langkah 2>" , "counterexample_sha256" : "<sha256 dari file cex>" , "class_local" : "fail" , "class_isolated" : "fail" , "freeze_reason" : "retained_input_failed_in_both_classifiers" } Biarkan kedaluwarsa sesuai dengan kebijakan yang sudah dienforce oleh repositori. Gerbang ini tidak menciptakan masa hidup. Jika Anda menambahkan field kedaluwarsa, hitung dari kebijakan tersebut dalam commit yang sama dengan sitasi. Tanggal yang diketik oleh agen tanpa aturan di sampingnya bukan kontrol.
