Pengiriman Pull Request & Batch Merge

Sebuah sesi berakhir dengan pull request di branch-nya sendiri, tidak pernah dengan commit di branch kerja. Itulah yang membuat dua puluh sesi atau lebih bisa berjalan bersamaan tanpa berantakan, dan alasannya mekanis: ketika lebih dari satu sesi menyentuh satu repositori, muncul tiga kegagalan, dan tidak satu pun memicu error di level git, karena setiap perintah valid jika berdiri sendiri.

KegagalanApa yang sebenarnya terjadiDicegah oleh
Dua sesi di satu branchPush kedua melakukan fast-forward atau ditolak, agent lalu memakai --force, dan PR sesi pertama kini membawa commit sesi keduaNama branch diturunkan oleh pr-registry claim, duplikat ditolak saat claim, load, dan save
Dua sesi di satu worktreegit worktree add gagal, atau sesi kedua bekerja di dalam checkout sesi pertama dan kedua diff menjadi kacauPath worktree diturunkan dengan cara yang sama, dan worktree berada di samping repositori, tidak pernah di dalamnya
Merge sesuai urutan selesaiSesi yang bergantung pada sesi lain masuk lebih dulu, lalu konflik dengan sisa batchUrutan topologis dihitung dari graf depends_on yang tercatat, nilai seri diputus berdasarkan nama agar urutannya bisa direproduksi

Dua aturan kepemilikan yang membuat konkurensi aman

Operasi tulis git hanya milik parent. Subagent mengedit file dan menjalankan test. Subagent tidak pernah menjalankan git commit, git add, git checkout, git switch, git merge, git rebase, git stash, git reset, git push, atau gh. Index git adalah state bersama yang bisa berubah dan tidak punya lock per penulis, sehingga dua subagent yang melakukan staging bersamaan menghasilkan commit yang memuat perubahan setengah jadi dari subagent lain, dan commit itu tidak pernah dites dalam bentuk tersebut. Parent mengintegrasikan per chunk dengan membaca git diff -- <permitted paths> dan melakukan staging dengan path eksplisit, tidak pernah git add ..

Satu sesi, satu PR. Dua puluh subagent di dalam satu sesi adalah satu PR. Dua puluh sesi adalah dua puluh PR. Satu PR per subagent mengubah run dua puluh sesi menjadi antrean merge berisi dua ratus PR.

State machine sesi

pr-registry.mjs menyimpan state, dan state-state itu ada untuk membuat dua kesalahan tertentu mustahil terjadi:

isolated → active → verified → open → merged
                                    ↘ closed
BatasanMengapa ini error keras
Nomor PR tidak bisa dicatat sebelum verifiedMencatat nomor PR menyiratkan pekerjaan sudah selesai dan diperiksa, jadi isolated → open akan melewati gate yang membuat merge aman
Hanya sesi open yang punya PR yang bisa di-mergeRun lokal yang hijau saja belum menjadikan sebuah sesi siap di-merge
merged membutuhkan plan Complete dan issue yang sudah ditutupPlan berubah menjadi Complete setelah debt sweep (penyisiran utang), jadi merge yang tercatat saat plan atau issue masih terbuka berarti ada langkah penutup yang terlewat. state <s> merged keluar dengan kode 1 dan mencetak perintah perbaikannya; --allow-open-plan mengesampingkannya dengan peringatan, dan --repo <path> mengarahkannya ke plan milik repositori lain
merged dan closed bersifat terminalMe-revert atau mengulang sebuah sesi berarti sesi baru dengan branch baru. File yang bisa "membatalkan merge" menyembunyikan revert dari urutan merge
Sesi yang ditutup tidak menggeser basemerged adalah alasan untuk rebase karena ia memajukan origin/main; closed tidak, sehingga surface tidak pernah mencantumkannya sebagai sudah masuk, sementara order tetap memperlakukannya sebagai dependensi yang terpenuhi
Branch atau worktree duplikat ditolakRegistry yang melaporkan sukses untuk tata letak yang akan menghilangkan pekerjaan lebih buruk daripada tidak punya registry sama sekali
bun scripts/pr-registry.mjs claim --plan <plan-id> --session <slug> [--depends-on <slug>,<slug>]
bun scripts/pr-registry.mjs state <session> <isolated|active|verified|open|merged|closed>
bun scripts/pr-registry.mjs state <session> merged [--repo <path>] [--allow-open-plan]
bun scripts/pr-registry.mjs pr <session> --number 42
bun scripts/pr-registry.mjs order       # topological merge order
bun scripts/pr-registry.mjs surface w3  # what must rebase first, what blocks it
bun scripts/pr-registry.mjs status

claim mencetak perintah git worktree add persis yang harus dijalankan, dan bersifat idempoten: claim yang diulang setelah sesi crash mengembalikan slot yang sama, bukan mengalokasikan slot kedua.

Branch turunannya adalah <plan-id>/<session-slug>, tanpa prefiks tool atau workflow. Dulu ada prefiks ai/, dan prefiks itu dihapus dengan alasan yang sama seperti aturan attribution-footer di bawah: nama branch adalah riwayat permanen yang bisa dibaca publik, sehingga sebuah prefiks menegaskan kepengarangan di satu-satunya artefak yang tidak bisa disensor siapa pun setelahnya. Plan id sudah memuat tanggal dan deskripsi pekerjaannya. Slot yang di-claim sebelum perubahan ini tetap memakai branch yang sudah di-claim-nya, jadi tidak ada migrasi dan tidak ada rename yang perlu dibatalkan. pr.registry.json sengaja di-gitignore. File ini adalah state live per mesin yang mencatat branch mana yang sedang dipegang setiap sesi yang berjalan saat ini; meng-commit-nya berarti menggabungkan sesi yang sedang berjalan dari dua puluh mesin ke dalam satu file dan menjamin konflik pada claim berikutnya.

Melakukan merge dua puluh PR

Satu per satu, sesuai urutan yang dicetak order, dan setiap merge membawa buktinya sendiri:

  1. Rebase branch sesi tersebut ke origin/main tepat sebelum merge-nya sendiri. Base bergeser di setiap merge, jadi branch yang di-rebase pada posisi 3 sudah tertinggal saat tiba di posisi 7. surface <s> melaporkan sesi mana saja yang sudah masuk sejak branch itu dibuat.
  2. Selesaikan konflik apa pun di branch sesi tersebut, tidak pernah di base branch, lalu jalankan ulang verifikasi sesi itu. Mengedit base untuk "memperbaiki" konflik menghasilkan perubahan yang tidak bisa diatribusikan atau di-review oleh sesi mana pun.
  3. Merge PR yang satu ini.
  4. Jalankan ulang pemeriksaan lokal di base yang baru. Run itulah bukti untuk merge tersebut.

Mengumpulkan dua puluh merge sekaligus lalu mengetesnya di akhir membuat sembilan belas di antaranya tidak terverifikasi. Sesi yang tidak bisa dibuat siap merge dilaporkan dan dilewati sementara batch tetap berjalan; itu adalah status, bukan alasan untuk membekukan sembilan belas sesi lainnya. Sesi yang sudah di-merge keluar dari urutan dan berhenti memblokir sesi yang bergantung padanya, dan siklus dependensi ditolak dengan menyebutkan siklusnya, karena tidak ada urutan yang valid untuk sebuah siklus.

Dua batas yang tidak dilewati tahap ini

CI remote dilaporkan, tidak pernah diadopsi. Pemeriksaan repositori ini berjalan secara lokal sesuai kebijakan, jadi run GitHub Actions yang hijau adalah bukti dari penulisnya tentang sebuah commit, bukan bukti dari sesi ini tentang working tree. Membacanya sebagai verifikasi adalah kesalahan yang sama dengan melakukan push untuk memicu runner milik orang lain.

Membuat review dan memposting review adalah dua tindakan berbeda. Komentar yang diposting adalah artefak yang lebih pendek daripada laporan internal: verdict, temuan yang memblokir, tidak lebih. Manusia membaca teks persisnya terlebih dahulu. Lihat templates/pr-review-template.md untuk tabel cakupan, aturan line-anchoring, dan verdict biner.