Sari la conținut

Tichete și delegare

Un tichet este unitatea de lucru pe care o urmărește Control Center. Este în mod deliberat un artefact prostesc: un titlu, un conținut, o stare, un proprietar și un loc într-un arbore. El nu este lucrul împotriva căruia execută agenții — munca agentului trăiește în conversații, iar rezultatul structurat al unei rulări trăiește în jurnalul rulării.

Atribuirea înregistrează proprietatea; nu trimite nimic

Secțiune intitulată „Atribuirea înregistrează proprietatea; nu trimite nimic”

Acesta este cel mai important lucru pe care trebuie să îl înțelegi corect despre tichete.

Setarea assignedAgentId scrie un câmp și publică un eveniment de domeniu TicketAssigned. Acel eveniment este un semnal de audit și de notificare și un trigger de pipeline. Atribuirea către un agent nu pornește nicio rulare. Nu există niciun dispecer de tichete care să supravegheze assignedAgentId și să trezească acel agent.

Excepția este o echipă: când este setat assignedTeamId, TeamRoutingService trimite liderul echipei împreună cu protocolul de operare și lista membrilor.

Dacă vrei ca un anumit agent să lucreze la un tichet, îi ceri asta într-o conversație, sau un pas de pipeline îl trimite, sau un alt agent îi deleagă sarcina. Să atribui un tichet unui agent și să aștepți este singurul lucru care nu va produce niciodată muncă.

Un tichet poate fi pur local sau susținut de un tracker extern, iar el le poartă pe amândouă pe un singur rând.

Oglinda — furnizor, cheie externă, URL, titlu, descriere, prioritate, etichete, stare brută și normalizată, marcaje temporale — este un cache atunci când tichetul este la distanță. Acolo, sursa de adevăr este sistemul de la distanță, iar o reîmprospătare rescrie oglinda în întregime.

Suprapunerea — atribuire, delegare, legătura cu spațiul, părinte, proiect, PR-uri legate — există doar în Control Center. Tracker-ul nu știe nimic despre ea, iar o reîmprospătare nu o atinge niciodată.

Această separare este ceea ce face sincronizarea sigură: o preluare de la furnizor poate fi distructivă pentru oglindă fără să piardă vreodată metadatele de orchestrare suprapuse peste ea.

Graful ciclului de viață îi leagă pe agenți, nu pe tine

Secțiune intitulată „Graful ciclului de viață îi leagă pe agenți, nu pe tine”

Stările curg backlog → open → inProgress → inReview → done, cu blocked ca buclă laterală și failed / cancelled ca celelalte stări finale.

Graful de tranziții este impus doar pe calea agentului și a automatizării — instrumentele MCP și procesele de reconciliere. O tranziție ilegală acolo este înregistrată în jurnal și ignorată, astfel încât un agent confuz nu poate scoate un tichet înapoi dintr-o stare finală.

Orice modificare făcută de utilizator în interfață transmite force: true și ocolește complet graful. Un om poate muta un tichet în orice stare listată de selector — inclusiv redeschiderea uneia finale. Selectorul nu oferă failed; agenții o setează prin fail_ticket. Graful este o barieră de protecție pentru automatizare, nu o regulă despre cum este voie să evolueze munca.

TicketWorkflowService deține fiecare mutație printr-un singur punct de trecere care încarcă rândul, verifică faptul că aparține spațiului de lucru al apelantului și scrie cu un version așteptat, astfel încât două editări simultane să nu se poată suprascrie reciproc în tăcere.

Pentru tabelul complet al stărilor, tranzițiile, lista câmpurilor și tipurile de relații, vezi Ciclul de viață al tichetelor.

Fiecare tichet are un originKind. Enumerația are cinci valori — manual, pipelineStep, agentDelegation, externalSync, recovery — dar astăzi se scriu doar două: manual (valoarea implicită la createTicket, inclusiv pentru copiii delegați) și externalSync (motorul de sincronizare, la o preluare de la furnizor). TicketWorkflowService.createTicket nu primește un argument de origine, așa că pipelineStep, agentDelegation și recovery nu ajung niciodată pe un rând.

Delegarea este locul în care un agent creează muncă pentru un alt agent și este punctul în care privilegiile ar putea scăpa, așa că protecțiile stau pe server, într-un punct de trecere, nu în instrucțiunile din prompt.

delegate_task trece prin TicketWorkflowService.delegateGuarded, care calculează adâncimea și rădăcina copilului pornind de la lanțul de părinți și apoi rulează toate cele patru verificări DelegationGuards: un salt care ar depăși un plafon de adâncime de 3, un salt înapoi la un agent aflat deja în lanț (detectarea ciclurilor), un plafon de autonomie (nivelul efectiv al delegatului în spațiu nu trebuie să îl depășească pe cel al delegatorului) și o anvelopă bugetară (delegarea facturează bugetul rămas de oprire forțată al delegatorului și nu poate emite mai mult). Configurarea de producție furnizează ambele porturi de rezolvare. Autonomia și bugetul sunt sărite când from_agent_id este omis (de asemenea, trece un buget nelimitat / fără politică). Un refuz este aruncat ca DelegationRefusedException, iar mesajul său ajunge la agentul care deleagă, cuvânt cu cuvânt — un refuz zgomotos, niciodată o operație fără efect, în tăcere.

delegate_ticket este fratele mai vechi, neprotejat: apelează direct createTicket și sare peste fiecare protecție. Preferă delegate_task.

Nu confunda plafonul de adâncime al delegării (3, pe lanțurile delegate_task) cu plafonul de imbricare a subagenților al harness-ului integrat (2). Sunt limite diferite pentru mecanisme diferite.

Relațiile de părinte și sub-sarcină trăiesc în tickets.parent_ticket_id, deținute de setParent / clearParent. Ele nu sunt rânduri ticket_links, așa că orice citește relațiile unui tichet trebuie să combine ambele surse.

ticket_links păstrează muchiile direcționate dintre tichete care, altfel, nu au legătură între ele:

Tip de legătură Semnificație
blocks Sursa o blochează pe cea țintă
relatesTo Cele două tichete sunt înrudite (simetric)
duplicateOf Sursa este un duplicat al țintei

Un proiect este o grupare de tichete, limitată la spațiul de lucru, în jurul unui obiectiv comun. Proiectele există doar în Control Center și nu se sincronizează niciodată cu un furnizor extern.

Rândurile TicketCollaborator sunt modul în care mai mulți principali sunt atașați unui tichet, cu un rol de assignee, collaborator sau reviewer. Oamenii și agenții sunt rânduri egale — un principalId plus un collaboratorType — fără nicio valoare santinelă pentru „utilizator” și fără nicio cheie străină către vreunul dintre tabele.

Tichetul din Control Center este cel principal. Ștergerea unui tichet este doar locală, așa că un tichet susținut de un furnizor pe care îl ștergi nu este șters și din tracker și poate reapărea la următoarea sincronizare. Colaboratorii și tichetele copil se șterg în cascadă.

Acreditările adaptorului se rezolvă din depozitele de acreditări ale serverului (o cheie Linear sau un token GitHub lipit în Setări este preluat la următoarea cerere; mediul doar alimentează inițial acele depozite).

Niciun nod de pipeline nu creează, nu finalizează și nu anulează tichete — paleta nu are un astfel de pas, iar motorul nu apelează TicketWorkflowService. Un trigger de pipeline se poate totuși declanșa pe TicketAssigned, TicketCompleted, TicketFailed sau TicketCancelled (aceste patru sunt evenimentele de tichet pe care EventPayloadMapper le mapează efectiv). Nu există nicio coloană pipelineRunId pe tichet; cuplarea cu pipeline-urile trăiește în jurnalul rulărilor agentului.