Tickets en delegatie
Een ticket is de werkeenheid die Control Center bijhoudt. Het is met opzet een dom artefact: een titel, een tekst, een status, een eigenaar en een plek in een boom. Het is niet het ding waartegen agents uitvoeren — agentwerk leeft in gesprekken en de gestructureerde uitvoer van een run staat in het runlogboek.
Toewijzing legt eigenaarschap vast; ze dispatcht niets
Sectie getiteld “Toewijzing legt eigenaarschap vast; ze dispatcht niets”Dit is het allerbelangrijkste om goed te hebben bij tickets.
Als je assignedAgentId instelt, wordt er een veld geschreven en wordt een
TicketAssigned domeingebeurtenis
gepubliceerd. Die gebeurtenis is een audit- en meldingssignaal en een
pipelinetrigger. Toewijzing aan een agent start geen run. Er is geen
ticketdispatcher die op assignedAgentId let en die agent wekt.
De uitzondering is een team: wanneer assignedTeamId is ingesteld, dispatcht
TeamRoutingService de teamleider met het werkprotocol en de ledenlijst.
Wil je dat een specifieke agent aan een ticket werkt, dan vraag je het in een gesprek, of een pipelinestap dispatcht die agent, of een andere agent delegeert ernaar. Een ticket aan een agent toewijzen en dan wachten is het ene ding dat nooit werk oplevert.
Spiegel en overlay
Sectie getiteld “Spiegel en overlay”Een ticket kan puur lokaal zijn of ondersteund worden door een externe tracker, en het draagt beide op één rij.
De spiegel — provider, externe sleutel, URL, titel, beschrijving, prioriteit, labels, ruwe en genormaliseerde status, tijdstempels — is een cache wanneer het ticket extern staat. De externe tracker is daar de bron van waarheid en een verversing herschrijft de spiegel in zijn geheel.
De overlay — toewijzing, delegatie, ruimtekoppeling, ouder, project, gekoppelde PR’s — bestaat alleen in Control Center. De tracker weet er niets van en een verversing raakt het nooit aan.
Die splitsing is wat synchroniseren überhaupt veilig maakt: een pull bij de leverancier kan verwoestend zijn voor de spiegel zonder ooit de orkestratiemetadata te verliezen die erbovenop ligt.
De levenscyclusgraaf bindt agents, niet jou
Sectie getiteld “De levenscyclusgraaf bindt agents, niet jou”Statussen lopen backlog → open → inProgress → inReview → done, met blocked
als zijlus en failed / cancelled als de andere eindtoestanden.
De transitiegraaf wordt alleen op het agent- en automatiseringspad afgedwongen — MCP-tools en reconcilers. Een ongeldige transitie wordt daar gelogd en genegeerd, zodat een in de war geraakte agent een ticket niet achteruit uit een eindtoestand kan laten lopen.
Elke door de gebruiker veroorzaakte wijziging in de UI geeft force: true mee
en omzeilt de graaf volledig. Een mens mag een ticket naar elke status
verplaatsen die de keuzelijst toont — inclusief het heropenen van een
eindtoestand. De keuzelijst biedt failed niet aan; agents stellen die in via
fail_ticket. De graaf is een vangrail voor automatisering, niet een regel over
hoe werk mag verlopen.
TicketWorkflowService bezit elke mutatie via één centraal controlepunt dat de
rij laadt, controleert dat die bij de werkruimte van de aanroeper hoort en
schrijft met een verwachte version, zodat twee gelijktijdige bewerkingen
elkaar niet stil kunnen overschrijven.
Zie Ticketlevenscyclus voor de volledige statustabel, transities, veldenlijst en relatiesoorten.
Herkomst: hoe een ticket is ontstaan
Sectie getiteld “Herkomst: hoe een ticket is ontstaan”Elk ticket heeft een originKind. De enum heeft vijf waarden — manual,
pipelineStep, agentDelegation, externalSync, recovery — maar er worden
vandaag maar twee geschreven: manual (de standaardwaarde bij createTicket,
inclusief gedelegeerde kinderen) en externalSync (de synchronisatie-engine,
bij een pull bij de leverancier). TicketWorkflowService.createTicket neemt
geen herkomstargument, dus pipelineStep, agentDelegation en recovery
belanden nooit op een rij.
Bewaakte delegatie
Sectie getiteld “Bewaakte delegatie”Delegatie is waar een agent werk voor een andere agent creëert, en het is de plek waar privileges kunnen weglekken; daarom staan de controles server-side op één centraal punt in plaats van in promptinstructies.
delegate_task loopt via TicketWorkflowService.delegateGuarded, dat de diepte
en de wortel van het kind berekent uit de ouderketen en dan alle vier de
controles van DelegationGuards uitvoert: een sprong die een dieptelimiet van
3 zou overschrijden, een sprong terug naar een agent die al in de keten zit
(cyclusdetectie), een autonomieplafond (het effectieve niveau van de
gedelegeerde in de ruimte mag niet hoger zijn dan dat van de delegator) en een
budgetenvelop (delegatie schrijft af op het resterende hard-stopbudget van
de delegator en kan niet meer bijmaken). De productieopzet levert beide
resolver-poorten. Autonomie en budget worden overgeslagen wanneer
from_agent_id ontbreekt (een onbeperkt budget of een budget zonder beleid
passeert ook). Een weigering wordt gegooid als een
DelegationRefusedException waarvan het bericht woordelijk bij de delegerende
agent terechtkomt — een luide weigering, nooit een stille no-op.
delegate_ticket is het oudere, ongebewaakte broertje: het roept
createTicket rechtstreeks aan en slaat elke controle over. Gebruik bij
voorkeur delegate_task.
Verwar het dieptelimiet van delegatie (3, op ketens van delegate_task) niet
met het nestinglimiet voor subagents van de ingebouwde harness (2). Het zijn
verschillende limieten op verschillende mechanismen.
Hiërarchie, koppelingen en projecten
Sectie getiteld “Hiërarchie, koppelingen en projecten”Ouder-kindrelaties en subissue-relaties leven op tickets.parent_ticket_id,
beheerd door setParent / clearParent. Het zijn geen rijen in
ticket_links, dus alles wat de relaties van een ticket leest, moet beide
bronnen samenvoegen.
ticket_links bevat de gerichte randen tussen verder niet-verwante tickets:
| Koppelingstype | Betekenis |
|---|---|
blocks |
De bron blokkeert het doel |
relatesTo |
De twee tickets zijn verwant (symmetrisch) |
duplicateOf |
De bron is een duplicaat van het doel |
Een project is een werkruimtegebonden groepering van tickets rond een gedeeld doel. Projecten bestaan alleen in Control Center en synchroniseren nooit naar een externe provider.
Medewerkers
Sectie getiteld “Medewerkers”Rijen van TicketCollaborator zijn hoe meer dan één principal aan een ticket
wordt gekoppeld, met een rol van assignee, collaborator of reviewer.
Mensen en agents zijn gelijkwaardige rijen — een principalId plus een
collaboratorType — zonder sentinelwaarde voor “de gebruiker” en zonder
foreign key naar een van beide tabellen.
Externe synchronisatie
Sectie getiteld “Externe synchronisatie”Het ticket van Control Center is leidend. Een ticket verwijderen is alleen lokaal, dus een ticket dat door een leverancier wordt ondersteund en dat je verwijdert, wordt niet op de tracker verwijderd en kan bij de volgende synchronisatie weer opduiken. Medewerkers en kindtickets worden mee verwijderd.
De inloggegevens van adapters worden opgehaald uit de inloggegevensopslag van de server (een Linear-sleutel of GitHub-token die je in Instellingen plakt, wordt bij het volgende verzoek opgepikt; de omgeving levert alleen de beginvulling voor die opslag).
Tickets en pipelines
Sectie getiteld “Tickets en pipelines”Geen enkel pipelineknooppunt maakt, voltooit of annuleert tickets — het palet
heeft zo’n stap niet en de engine roept TicketWorkflowService niet aan. Een
pipelinetrigger kan nog steeds afgaan op TicketAssigned, TicketCompleted,
TicketFailed of TicketCancelled (die vier zijn de ticketgebeurtenissen die
EventPayloadMapper daadwerkelijk mapt). Er is geen kolom pipelineRunId op
het ticket; de koppeling met pipelines staat in het runlogboek van de agent.
Zie ook
Sectie getiteld “Zie ook”- Pipelines en automatisering: ticketgebeurtenissen kunnen een pipeline starten
- Orkestratie: waar een DAG van subtickets vandaan komt
- Het agentmodel: aan wie een ticket is toegewezen
- Domeingebeurtenissen: de levenscyclusgebeurtenissen van tickets
- Ticketlevenscyclus: statussen, velden, transities, relaties
- Tickets maken en beheren
- Werk delegeren aan agenten
- Werk organiseren met projecten