Hoppa till innehåll

Domänhändelser

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.

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

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

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
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
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

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.

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.

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
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.

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
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å.

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

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.

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.