Domänhändelser
Händelsebussen
Avsnitt med rubriken “Händelsebussen”DomainEventBus är en publicerings-/prenumerationsbuss för utsändning i samma
process. Utgivare anropar publish(event); prenumeranter konsumerar en typad
on<T>()-ström. Varje händelse implementerar DomainEvent och bär occurredAt.
Bussen körs inuti cc_server. Varje utgivare och varje levande prenumerant
finns där. Ingen klient ser den här bussen – servern vidarebefordrar en kurerad
delmängd som notifications/*-ramar i JSON-RPC, filtrerade per prenumerant
efter arbetsytans medlemskap.
| Mått | Antal |
|---|---|
| Konkreta händelseklasser | 54 |
Källfiler (packages/cc_domain/lib/core/domain/events/) |
14 (plus domain_event_bus.dart) |
| Abstrakta basklasser som aldrig publiceras direkt | 1 (TaskLifecycleEvent, en sluten hierarki) |
Varje händelse i katalogen nedan finns i den enda katalogen; det finns inga domänhändelser deklarerade någon annanstans.
Arbetsyte-, agent- och repohändelser
Avsnitt med rubriken “Arbetsyte-, agent- och repohändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
WorkspaceCreated |
workspaceId |
Arbetsytan skapas |
AgentRunCompleted |
agentId, runId?, workspaceId?, conversationId? |
Agenten avslutar en körning (lyckad eller misslyckad) |
AgentAwaitingInput |
workspaceId, kind, summary, spaceId?, conversationId?, agentId?, agentName? |
En agent börjar vänta på en människa: ett godkännande, en ask_user-fråga eller en körning som står still på grund av inloggningsuppgifter (kind är approval, question eller credential) |
RepoAdded |
repoId, path, workspaceId |
Ett repo registreras; startar kodindexering i bakgrunden |
SkillUpdated |
workspaceId, slug, origin, computedHash, scanVerdict? |
En skill installeras eller uppdateras och bär sitt scanresultat från leveranskedjan |
PR- och granskningshändelser
Avsnitt med rubriken “PR- och granskningshändelser”Det första blocket är PR:ens egen livscykel. Det andra är bevakningen av egna
PR:er: signaler om en PR som du har öppnat, som var och en bär forUserId så
att avsökningen kan dirigera dem till personen de gäller i stället för att sända
ut dem.
| Händelse | Nyttolast | Utlöses när |
|---|---|---|
PullRequestPublished |
prId, workspaceId, repoOwner, repoName |
En agent öppnar en PR |
PullRequestStatusChanged |
status, workspaceId, prId?, repoFullName?, prNumber? |
En PR slås samman, stängs, öppnas, återöppnas eller godkänns |
PrMerged |
prId, workspaceId, agentId |
En PR slås samman – en smal signal enbart för sammanslagning, bevarad för analys och aviseringar |
PrReviewRequested |
workspaceId, repoOwner, repoName, prNumber, prTitle |
GitHub begär serveranvändarens granskning (aviseringsavsökningen, review_requested) |
PrMentioned |
workspaceId, repoOwner, repoName, prNumber, prTitle |
Serveranvändaren nämns i en PR (aviseringsavsökningen, mention) |
ExternalPrMerged |
workspaceId, repoOwner, repoName, prNumber, prTitle, mergedByLogin? |
En externt spårad PR (inte från en agent) slogs samman, upptäckt av GitHubs aviseringsavsökning; mappas till aviseringskategorin prMerged |
ExternalPrDetected |
repoOwner, repoName, prNumber, prTitle, author, workspaceId? |
En PR utan agent hittades via avsökning – endast för pipelines (driver external_pr_welcome), höjer ingen avisering |
PrHeadChanged |
repoOwner, repoName, prNumber, prTitle, previousHeadSha, headSha, workspaceId |
PR:ens head-SHA flyttades – författaren pushade |
ReviewBecameStale |
workspaceId, spaceId, repoOwner, repoName, prNumber, prTitle, reviewedHeadSha, headSha |
En avslutad AI-granskning beskriver inte längre den PR den granskade. Utlöses bara när det finns en granskning för den ersatta commiten, så den förblir en signal i stället för en ping vid varje push |
Bevakningen av egna PR:er
Avsnitt med rubriken “Bevakningen av egna PR:er”Alla sex bär workspaceId, repoOwner, repoName, prNumber, prTitle och en
valfri forUserId.
| Händelse | Ytterligare nyttolast | Utlöses när |
|---|---|---|
PrMergeReadinessChanged |
ready, reason |
En PR du har skapat blev sammanslagningsbar, eller slutade vara det |
PrReviewDecisionChanged |
decision, reviewersRemaining, approverLogin? |
En granskare godkände, begärde ändringar eller fick ett godkännande avvisat |
PrChecksStatusChanged |
failing, failingCheckName?, failingCheckUrl? |
CI blev rött, eller återhämtade sig |
PrCommentMentioned |
commentId, authorLogin, bodyPreview, isReviewComment, threadId?, path?, line? |
Någon nämnde dig i en PR-kommentar eller granskningskommentar |
PrThreadReplied |
commentId, authorLogin, bodyPreview, threadId?, path?, line? |
Någon svarade i en granskningstråd du är med i |
PrThreadResolved |
threadId, commentId?, path?, line? |
Någon löste en granskningstråd du är med i |
Meddelandehändelser
Avsnitt med rubriken “Meddelandehändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
MessageReceived |
spaceId, messageId, senderName, contentPreview, isAgentMessage, workspaceId?, mentions, requestedByUserId?, senderUserId? |
Ett nytt meddelande kommer in |
SpaceCreated |
spaceId, workspaceId |
En yta skapas |
SpaceDeleted |
spaceId, workspaceId |
En yta tas bort |
SpaceProvisioningChanged |
workspaceId, spaceId, status, step? |
Ytans arbetsyta går in i provisionering, når ett steg (klona ett repo, checka ut en PR, sätta upp en agent) eller växlar till redo/misslyckad – chattbryggan berättar om det på sitt uppgiftskort |
Ärendehändelser
Avsnitt med rubriken “Ärendehändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
TicketCreated |
ticketId, workspaceId |
Ett ärende skapas |
TicketAssigned |
ticketId, ticketTitle, ticketBody?, ticketUrl?, assignedAgentId?, assigneeType, assignedTeamId?, workspaceId |
Ärendet tilldelas en principal eller ett team |
TicketCompleted |
ticketId |
Arbetet slutförs (terminalt) |
TicketFailed |
ticketId, errorMessage |
Agenten misslyckas (terminalt) |
TicketCancelled |
ticketId |
Ärendet avbryts (terminalt) |
TicketStatusChanged |
ticketId, workspaceId, from, to |
Varje statusändring |
TicketReassigned |
ticketId, workspaceId, fromAgentId?, toAgentId? |
Ärendet tilldelas på nytt |
TicketDetailsUpdated |
ticketId, workspaceId |
Titel, beskrivning eller prioritet ändras |
Händelser i uppgiftslivscykeln
Avsnitt med rubriken “Händelser i uppgiftslivscykeln”Den enhetliga strömmen för uppgiftslivscykeln – en dispatchad agentkörning,
nycklad på sitt körloggs-id. Varje händelse bär taskId, en monoton seq per
uppgift, workspaceId?, agentId? och en phase; raderna nedan listar bara de
ytterligare fälten.
| Händelse | Nyttolast | Utlöses när |
|---|---|---|
TaskDispatched |
— | Uppgiften lämnas till en backend för körning |
TaskRunning |
— | Uppgiften började producera utdata |
TaskWaitingLocalDirectory |
lockedPath, holderTaskId? |
Uppgiften parkeras – en annan uppgift äger sökvägslåset på disken som den behöver |
TaskProgress |
note? |
Framstegskontrollpunkt mitt i körningen |
TaskMessage |
messageType, content |
Strömmat meddelande (text/thinking/tool_use/tool_result/error); rapporteras under fasen progress |
TaskCompleted |
summary? |
Uppgiften slutfördes |
TaskFailed |
errorMessage |
Uppgiften avslutades med ett fel |
TaskCancelled |
— | Uppgiften avbröts före slutförandet |
Enumen TaskPhase har också en medlem queued, men ingenting publicerar en
köad händelse – det finns ingen klass TaskQueued. En uppgifts första
observerbara ram är TaskDispatched.
Pipelinehändelser
Avsnitt med rubriken “Pipelinehändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
PipelineRunCompleted |
workspaceId, pipelineRunId, templateId |
Körningen slutförs |
PipelineRunCancelled |
workspaceId, pipelineRunId, templateId |
Körningen avbryts (av användaren eller systemet) – ett avsiktligt stopp, inte ett fel |
PipelineRunFailed |
workspaceId, pipelineRunId, templateId, errorMessage |
Körningen misslyckas |
Bara terminala övergångar publiceras. Det finns ingen PipelineRunStarted och
ingen händelse per steg: ett stegs framsteg når klienter via körningens egna
rader och uppgiftslivscykelströmmen för vilken agent det än dispatchade, inte via
bussen.
Observerbarhetshändelser
Avsnitt med rubriken “Observerbarhetshändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
ActivityLogged |
id, actorType, actorId?, action, entityType, entityId?, details?, workspaceId?, runId? |
En post i granskningsloggen skapas |
BudgetThresholdCrossed |
scopeType, scopeId, spentCents, budgetCents, isHardStop |
Utgifterna passerar tröskeln |
Identitets- och medlemskapshändelser
Avsnitt med rubriken “Identitets- och medlemskapshändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
WorkspaceMemberAdded |
workspaceId, userId, role |
En användare går med i en arbetsyta (inlösen av inbjudan eller tillägg av administratör) |
WorkspaceMemberRemoved |
workspaceId, userId |
En medlem tas bort – den användarens livesessioner som är avgränsade till arbetsytan måste kontrollera åtkomsten igen direkt |
WorkspaceMemberRoleChanged |
workspaceId, userId, role |
En medlems roll ändras |
Medlemskap är hela identitetsytan på bussen. Skapande av användare och återkallning av enheter sker, men de publiceras inte som domänhändelser – återkallning verkställs direkt mot livesessioner i stället för att dirigeras via bussen.
Kalender- och möteshändelser
Avsnitt med rubriken “Kalender- och möteshändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
CalendarAuthExpired |
workspaceId, accountEmail |
En ansluten kontos OAuth-uppdateringstoken är permanent ogiltig (publiceras en gång per frånkopplingshändelse) |
MeetingStartingSoon |
workspaceId, eventId, title, startTime, meetingUrl? |
En kalenderhändelse börjar inom det konfigurerade förvarningsfönstret |
MeetingRecordingStopped |
workspaceId, meetingId, title, userNotes, transcript, summaryInstructions? |
En mötesinspelning slutförs och startar den inbyggda pipelinen meeting_summary |
Stationshändelser
Avsnitt med rubriken “Stationshändelser”| Händelse | Nyttolast | Utlöses när |
|---|---|---|
RigClosedEvent |
workspaceId, rigId, reason |
En station försvann, med sin stängningsorsak; konsumenter agerar bara på backendFailure – varje annan orsak är begärd eller åtföljs av en RigReaped |
RigControlChanged |
workspaceId, rigId, controller? |
En människa tog exklusiv kontroll över en station eller lämnade tillbaka den (controller är null vid släpp – händelsen registrerar inte vem som släppte) |
RigReaped |
workspaceId, rigId, reason, agentId? |
Systemet återtog en maskin: inaktivitet, TTL eller vräkning vid minnesbrist (rapporteras som idleTimeout), med den drivande agenten |
Att en station öppnas är inte en händelse. Starten slutförs och stationens
rad växlar till redo; ingenting publiceras, så det finns ingen RigOpened att
prenumerera på.
Deldomäner helt utan händelser
Avsnitt med rubriken “Deldomäner helt utan händelser”Flera delsystem som utifrån ser händelsedrivna ut är det inte. De listas här eftersom deras frånvaro är ett designbeslut värt att känna till innan du börjar leta efter en hook:
| Deldomän | Hur tillståndet i stället rör sig |
|---|---|
| Minne | record_memory_fact och liknande skriver och returnerar; recall läser. Ingenting publicerar vid ett faktum eller en konflikt |
| Orkestrering | Förslaget, dess godkännande och den genererade pipelinekörningen är rader och RPC-anrop |
| Plandokument | submit_plan skriver en revision; godkännandet materialiserar en orkestrering. Inget av dem annonseras |
| Artefakter | publish_artifact / revise_artifact skriver revisioner direkt |
| Godkännanden | Eskalering hanteras inuti arbetsflödestjänsten för godkännanden |
| Ärendesynk | Leverantörskoordinatorn prenumererar på ärendehändelserna ovan; inkommande webhooks tillämpas direkt |
| Kalenderuppdatering | En synk upsertar händelser och klienten läser om; det finns ingen uppdateringsutsändning |
| Worktree-sammanslagningar | Registreras i worktree_merge_log och läses därifrån |
Prenumeranter
Avsnitt med rubriken “Prenumeranter”Varje prenumerant nedan konstrueras inuti runCcServer (eller en tjänst som den
bygger). Det finns ingen prenumerant på klientsidan.
| Prenumerant | Händelser den konsumerar |
|---|---|
WorkspaceSeeder |
WorkspaceCreated |
| Sådd av eval-sviten för startpaketet (inline) | WorkspaceCreated |
| Provisionering av chattyta (inline) | SpaceCreated |
PipelineTriggerDispatcher |
Varje DomainEvent; varje aktiverad trigger filtrerar på sin egen typ |
SubPipelineResumeListener |
PipelineRunCompleted, PipelineRunFailed |
PipelineCostRollupListener |
AgentRunCompleted |
BudgetEvaluationListener |
AgentRunCompleted |
MeetingSummaryReconciler |
PipelineRunCompleted, PipelineRunFailed, PipelineRunCancelled (endast körningar av meeting_summary) |
PipelineStepResumeListener |
AgentRunCompleted |
AgentRunTaskCompleter |
AgentRunCompleted |
GoalSupervisor |
AgentRunCompleted |
CheckerDispatchListener |
AgentRunCompleted |
TeamRoutingService |
AgentRunCompleted, TicketAssigned |
OrchestrationRunListener |
PipelineRunCancelled, PipelineRunFailed |
MultiVendorTicketSyncCoordinator |
TicketCreated, TicketAssigned, TicketReassigned, TicketStatusChanged, TicketDetailsUpdated |
WorktreeGcListener |
TicketCompleted, TicketCancelled, SpaceDeleted, PrMerged, PullRequestStatusChanged |
ChatBridgeService |
MessageReceived, SpaceProvisioningChanged |
ActivityLogPersister |
ActivityLogged |
RigEventListener |
RigControlChanged, RigReaped, RigClosedEvent – injicerar ett meddelande på klarspråk i den drivande agentens styrkanal |
StaleReviewWatcher |
PrHeadChanged – publicerar ReviewBecameStale bara när det finns en avslutad granskning för den ersatta commiten |
GitHubPrConversationBridge |
AgentRunCompleted – utgående svar i PR-samtal |
NotificationFeedRecorder |
De tjugotvå händelserna i aviseringsklassen nedan |
RemoteEventForwarder |
De tjugotvå plus TicketReassigned och varje TaskLifecycleEvent. De tre medlemskapshändelserna ogiltigförklarar bara dess medlemskapscache per arbetsyta; de vidarebefordras inte som ramar |
LocalRpcServer / RemoteRelayHost |
WorkspaceMemberRemoved – släpper den användarens anslutna arbetsyteprenumerationer; socketen förblir öppen |
TicketAssigned är en gransknings- och aviseringssignal och en pipelinetrigger.
Tilldelning till en agent registrerar ägarskap och startar ingen körning – det
finns ingen ärendedispatch. Tilldelning till ett team (assignedTeamId satt) är
undantaget: TeamRoutingService dispatchar teamledaren.
TicketRemoteSyncHandler är deklarerad men konstrueras aldrig i
produktionskoden, så den prenumererar inte på något i dag. NotificationEventMapper
på klientsidan konstrueras bara i sitt eget test – den är kvarlevan av vägen i
samma process från tiden före uppdelningen i klient och server. Live-toastar
kommer från ramarna på tråden nedan.
Aviseringsmappning
Avsnitt med rubriken “Aviseringsmappning”På servern omvandlar NotificationFeedRecorder och RemoteEventForwarder dessa
händelser till trådramar av typen notifications/* (notification_wire.dart).
På klienten omvandlar RpcNotificationMapper → mapNotificationFrame en ram
till en AppNotification.
Det finns exakt sjutton aviseringskategorier. Flera händelser mappas till mer än en trådmetod, eftersom ramen bär kanten (misslyckades kontra återhämtade sig) medan kategorin bär frågan (”vad gör CI?”).
| Kategori | Källhändelse | Trådmetod |
|---|---|---|
newMessage |
MessageReceived |
notifications/message_received (nämner dig) |
agentRunCompleted |
MessageReceived |
notifications/message_received (is_agent_message, nämner inte dig) |
agentAwaitingInput |
AgentAwaitingInput |
notifications/agent_awaiting_input |
ticketAssigned |
TicketAssigned |
notifications/ticket_assigned |
ticketStatusChanged |
TicketStatusChanged |
notifications/ticket_status_changed |
pullRequestPublished |
PullRequestPublished |
notifications/pr_published |
prMerged |
PrMerged |
notifications/pr_merged |
prMerged |
ExternalPrMerged |
notifications/external_pr_merged |
prMentioned |
PrMentioned |
notifications/pr_mentioned |
prMentioned |
PrCommentMentioned |
notifications/pr_comment_mentioned |
reviewRequested |
PrReviewRequested |
notifications/pr_review_requested |
reviewStale |
ReviewBecameStale |
notifications/review_stale |
prMergeReadiness |
PrMergeReadinessChanged |
notifications/pr_ready_to_merge / pr_merge_blocked |
prReviewDecision |
PrReviewDecisionChanged |
notifications/pr_approved / pr_changes_requested / pr_review_dismissed |
prChecksStatus |
PrChecksStatusChanged |
notifications/pr_checks_failed / pr_checks_recovered |
prThreadActivity |
PrThreadReplied |
notifications/pr_thread_replied |
prThreadActivity |
PrThreadResolved |
notifications/pr_thread_resolved |
meetingStartsSoon |
MeetingStartingSoon |
notifications/meeting_starting_soon |
calendarAuthExpired |
CalendarAuthExpired |
notifications/calendar_auth_expired |
rigStatusChanged |
RigControlChanged |
notifications/rig_control_changed |
rigStatusChanged |
RigReaped |
notifications/rig_reaped |
rigStatusChanged |
RigClosedEvent |
notifications/rig_closed |
Ramen för stationens övertagande levereras inte tillbaka till den som tog över,
ett släpp filtreras inte (händelsen registrerar inte vem som släppte), och bara
en stängning med backendFailure ger en rig_closed-ram – de andra orsakerna är
antingen begärda eller redan täckta av återtaganderamen.
AgentAwaitingInput publiceras av AgentAwaitingInputPublisher, som bevakar
registren för godkännanden och blockerade inloggningsuppgifter efter nya poster
och får veta om varje ask_user-fråga av AgentQuestionService. En väntan är en
händelse; ingenting publiceras när väntan tar slut.
De fem kategorierna för egna PR:er bär forUserId, så de når skaparen i stället
för alla i arbetsytan.
RemoteEventForwarder vidarebefordrar dessutom TicketReassigned som
notifications/ticket_reassigned och varje TaskLifecycleEvent som
notifications/task_<phase>. Ingen av dem mappas till en aviseringskategori –
de driver live-UI, inte aviseringscentralen. Medlemskapshändelser vidarebefordras
inte som ramar: de ogiltigförklarar vidarebefordrarens cache, och
sessionsvärdarna släpper den borttagna medlemmens arbetsyteprenumerationer.