Lewati ke konten

Tiket dan delegasi

Tiket adalah unit pekerjaan yang dilacak Control Center. Tiket sengaja dibuat sebagai artefak yang bodoh: sebuah judul, isi, status, pemilik, dan posisi dalam sebuah pohon. Tiket bukan objek yang dieksekusi agen — pekerjaan agen hidup di percakapan dan keluaran terstruktur sebuah run berada di log run.

Penugasan mencatat kepemilikan; tidak mengirim apa pun

Bagian berjudul “Penugasan mencatat kepemilikan; tidak mengirim apa pun”

Inilah satu hal terpenting yang harus Anda pahami dengan benar tentang tiket.

Menetapkan assignedAgentId menulis sebuah kolom dan menerbitkan peristiwa domain TicketAssigned. Peristiwa itu adalah sinyal audit dan notifikasi sekaligus pemicu pipeline. Penugasan kepada agen tidak memulai run apa pun. Tidak ada pengirim tiket yang memantau assignedAgentId lalu membangunkan agen tersebut.

Pengecualiannya adalah tim: saat assignedTeamId ditetapkan, TeamRoutingService mengirimkan pemimpin tim beserta protokol operasional dan daftar anggotanya.

Jika Anda ingin agen tertentu mengerjakan sebuah tiket, mintalah kepadanya di sebuah percakapan, atau sebuah langkah pipeline mengirimkannya, atau agen lain mendelegasikan kepadanya. Menugaskan tiket kepada agen lalu menunggu adalah satu-satunya hal yang tidak akan pernah menghasilkan pekerjaan.

Sebuah tiket bisa sepenuhnya lokal atau didukung pelacak eksternal, dan keduanya berada pada satu baris yang sama.

Cermin — penyedia, kunci eksternal, URL, judul, deskripsi, prioritas, label, status mentah dan ternormalisasi, stempel waktu — adalah cache saat tiket bersifat jarak jauh. Di sana, sisi jarak jauh adalah sumber kebenaran dan penyegaran menulis ulang cermin sepenuhnya.

Lapisan tambahan — penugasan, delegasi, tautan space, induk, proyek, PR tertaut — hanya milik Control Center. Pelacak tidak tahu apa pun tentangnya dan penyegaran tidak pernah menyentuhnya.

Pemisahan itulah yang membuat sinkronisasi aman sejak awal: penarikan dari penyedia boleh merusak cermin tanpa pernah kehilangan metadata orkestrasi yang dilapiskan di atasnya.

Status berjalan backlog → open → inProgress → inReview → done, dengan blocked sebagai putaran samping dan failed / cancelled sebagai status terminal lainnya.

Graf transisi ditegakkan hanya pada jalur agen dan otomatisasi — alat MCP dan reconciler. Transisi ilegal di sana dicatat ke log dan diabaikan, sehingga agen yang bingung tidak dapat membawa tiket mundur keluar dari status terminal.

Setiap perubahan yang dipicu pengguna di UI meneruskan force: true dan melewati graf sepenuhnya. Manusia boleh memindahkan tiket ke status mana pun yang terdaftar di pemilih — termasuk membuka kembali status terminal. Pemilih tidak menawarkan failed; agen menetapkannya melalui fail_ticket. Graf adalah pagar pengaman untuk otomatisasi, bukan aturan tentang bagaimana pekerjaan boleh berjalan.

TicketWorkflowService memegang setiap mutasi melalui satu titik masuk tunggal yang memuat barisnya, memastikan baris itu milik ruang kerja pemanggil, dan menulis dengan version yang diharapkan sehingga dua penyuntingan bersamaan tidak dapat saling menimpa secara diam-diam.

Untuk tabel status lengkap, transisi, daftar kolom, dan jenis relasi, lihat Siklus hidup tiket.

Setiap tiket memiliki originKind. Enum ini punya lima nilai — manual, pipelineStep, agentDelegation, externalSync, recovery — tetapi baru dua yang ditulis saat ini: manual (nilai default pada createTicket, termasuk untuk tiket anak yang didelegasikan) dan externalSync (mesin sinkronisasi, saat penarikan dari penyedia). TicketWorkflowService.createTicket tidak menerima argumen asal, jadi pipelineStep, agentDelegation, dan recovery tidak pernah mengisi sebuah baris.

Delegasi adalah saat agen membuat pekerjaan untuk agen lain dan di situlah hak istimewa bisa bocor, karena itu penjaganya berada di sisi server pada satu titik masuk, bukan di dalam instruksi prompt.

delegate_task melewati TicketWorkflowService.delegateGuarded, yang menghitung kedalaman dan akar anak dari rantai induknya lalu menjalankan keempat pemeriksaan DelegationGuards: lompatan yang akan melewati batas kedalaman 3, lompatan kembali ke agen yang sudah ada di rantai (deteksi siklus), batas atas otonomi (tingkat efektif penerima delegasi di space tidak boleh melebihi tingkat pemberi delegasi), dan kerangka anggaran (delegasi membebankan sisa anggaran hard-stop milik pemberi delegasi dan tidak dapat mencetak anggaran baru). Pengkabelan produksi menyediakan kedua port resolver. Otonomi dan anggaran dilewati saat from_agent_id dihilangkan (anggaran tanpa batas / tanpa kebijakan juga lolos). Penolakan dilemparkan sebagai DelegationRefusedException yang pesannya sampai ke agen pendelegasi apa adanya — penolakan yang nyaring, bukan no-op yang senyap.

delegate_ticket adalah kerabat lama yang tanpa penjagaan: ia memanggil createTicket secara langsung dan melewati semua penjaga. Utamakan delegate_task.

Jangan mengacaukan batas kedalaman delegasi (3, pada rantai delegate_task) dengan batas penyarangan subagen milik harness bawaan (2). Keduanya adalah batas yang berbeda pada mekanisme yang berbeda.

Relasi induk dan sub-issue berada di tickets.parent_ticket_id, yang dikelola oleh setParent / clearParent. Relasi itu bukan baris ticket_links, jadi apa pun yang membaca relasi sebuah tiket harus menggabungkan kedua sumber.

ticket_links menyimpan sisi berarah antara tiket-tiket yang tidak berhubungan:

Jenis tautan Arti
blocks Sumber memblokir target
relatesTo Kedua tiket saling berhubungan (simetris)
duplicateOf Sumber adalah duplikat dari target

Proyek adalah pengelompokan tiket dalam cakupan ruang kerja menuju tujuan bersama. Proyek hanya milik Control Center dan tidak pernah disinkronkan ke penyedia eksternal.

Baris TicketCollaborator adalah cara lebih dari satu prinsipal dikaitkan ke sebuah tiket, dengan peran assignee, collaborator, atau reviewer. Manusia dan agen adalah baris yang setara — sebuah principalId plus collaboratorType — tanpa nilai sentinel untuk “pengguna” dan tanpa kunci asing ke salah satu tabel.

Tiket milik Control Center adalah yang utama. Menghapus tiket bersifat lokal saja, jadi tiket yang didukung penyedia yang Anda hapus tidak ikut terhapus di pelacak dan bisa muncul lagi pada sinkronisasi berikutnya. Kolaborator dan tiket anak ikut terhapus berjenjang.

Kredensial adapter diselesaikan dari penyimpanan kredensial server (kunci Linear atau token GitHub yang ditempel di Pengaturan akan terbaca pada permintaan berikutnya; lingkungan hanya menjadi nilai awal bagi penyimpanan itu).

Tidak ada node pipeline yang membuat, menyelesaikan, atau membatalkan tiket — palet tidak punya langkah semacam itu dan mesinnya tidak memanggil TicketWorkflowService. Pemicu pipeline tetap dapat menyala pada TicketAssigned, TicketCompleted, TicketFailed, atau TicketCancelled (keempatnya adalah peristiwa tiket yang benar-benar dipetakan EventPayloadMapper). Tidak ada kolom pipelineRunId pada tiket; keterkaitan pipeline berada di log run agen.