Domain-Ereignisse
Was ein Domain-Ereignis ist
Abschnitt betitelt „Was ein Domain-Ereignis ist“Domain-Ereignisse entkoppeln Features, damit sie kommunizieren können, ohne direkt voneinander abzuhängen. Statt dass Feature A Feature B aufruft, veröffentlicht Feature A ein Ereignis, und Feature B abonniert es.
DomainEventBus ist ein prozessinterner Broadcast-Bus nach dem
Publish/Subscribe-Muster. Publisher rufen publish(event) auf; Subscriber
konsumieren einen typisierten Strom on<T>(). Jedes Ereignis implementiert
DomainEvent und trägt occurredAt.
Der Bus läuft in cc_server. Jeder Publisher und jeder lebende Subscriber
lebt dort. Kein Client sieht diesen Bus. Was ein Client sieht, ist eine
kuratierte Teilmenge, die der Server als JSON-RPC-Frames notifications/*
erneut aussendet.
Warum überhaupt ein Bus
Abschnitt betitelt „Warum überhaupt ein Bus“Ohne Ereignisse ist jede Reaktion über Feature-Grenzen hinweg ein Import. Der Benachrichtigungspfad müsste das Agenten-Feature, das Pull-Request-Feature, die Tickets und die Besprechungen importieren, nur um zu wissen, wann ein Toast erscheinen soll. Und jedes davon müsste dann wissen, dass Benachrichtigungen existieren. Die Tickets müssten die Pipelines importieren, damit ein abgeschlossenes Ticket einen Lauf weiterschalten kann. Der Abhängigkeitsgraph verknotet sich, und der gemeinsame Kern hört auf, gemeinsam zu sein.
Ein Ereignis zu veröffentlichen löst das. Der Benachrichtigungspfad abonniert 21 Ereignisklassen und importiert keines der Features, die sie auslösen. Der Dispatcher der Pipeline-Trigger abonniert den ganzen Bus und weiß nichts über Pull Requests, Tickets oder Besprechungen. Die Beobachtbarkeit fasst Laufergebnisse zusammen, ohne in die Ausführung zu greifen.
Der Preis ist der übliche: Ein Publisher erkennt nicht, ob jemand zuhört, und
ein Listener, der nie erzeugt wird, bleibt still untätig.
TicketRemoteSyncHandler ist das bleibende Beispiel. Er ist deklariert, von
Tests abgedeckt und in der Produktion nie verdrahtet.
Was der Bus nicht ist
Abschnitt betitelt „Was der Bus nicht ist“Bei einer Sache, die der Bus nicht besitzt, lohnt sich Genauigkeit.
Das Audit-Protokoll ist keine Projektion des Ereignisstroms. Jede
verändernde RPC-Operation wird standardmäßig auditiert. RepoOp.audited steht
standardmäßig auf true, und eine Operation steigt nur aus, indem sie
audited: false deklariert, ein bewusster Akt, sichtbar an der Operation
selbst. Der Dispatcher hängt direkt nach einem erfolgreichen Aufruf die Zeile
„wer was getan hat und von wo“ an. DomainEventAuditBridge gibt es nicht.
ActivityLogPersister schreibt Zeilen in activity_log aus Ereignissen
ActivityLogged. Das ist ein eigener Kanal, getrennt vom RPC-Audit.
Der Ereignisbus ist der Transport für Benachrichtigungen und für Automatisierung. Die Buchführung, die als Quelle der Wahrheit gilt, ist er nicht.
Was der Bus tatsächlich antreibt
Abschnitt betitelt „Was der Bus tatsächlich antreibt“- Benachrichtigungen. 21 Ereignisklassen macht der Server zu Wire-Frames
notifications/*, schreibt sie in einen dauerhaften Feed je Arbeitsbereich und verteilt sie an verbundene Sitzungen. Einen Frame, dessenworkspace_ideinen Arbeitsbereich nennt, in dem der Benutzer der Sitzung kein Mitglied ist, verwirft der Server. Der Client filtert den Rest dann auf den Arbeitsbereich, den er gerade anzeigt. - Ereignisgesteuerte Automatisierung. Pipeline-Trigger abonnieren den Bus und starten passende Pipelines von selbst (siehe unten).
- Reaktionen im Lebenszyklus. Das Anlegen eines Arbeitsbereichs legt seinen CEO und seine Spezialisten an, dazu die eingebauten Pipeline-Vorlagen und die Eval-Suiten für den Einstieg. Ein abgeschlossener Agentenlauf setzt einen angehaltenen Pipeline-Schritt fort, schließt eine Aufgabe, versorgt den Zielsupervisor, kann einen benannten Prüfer wecken und kann die Teamleitung erneut anstoßen. Ein zusammengeführter PR oder ein gelöschter Bereich stößt die Garbage Collection der Worktrees an.
- Anbieterübergreifende Synchronisierung. Ein Koordinator, der auf fünf Ticket-Ereignisse hört, schiebt lokale Ticket-Änderungen an die konfigurierten Anbieter.
Ereigniskategorien
Abschnitt betitelt „Ereigniskategorien“Ereignisse decken die ganze Produktoberfläche ab. Im Überblick:
- Arbeitsbereiche, Agenten und Repos – Anlegen eines Arbeitsbereichs, Abschluss eines Laufs, Repo-Registrierung, Skill-Aktualisierungen
- Pull Requests – Veröffentlichen, Statusänderungen, Merges, Review-Anfragen, Erwähnungen, Beobachten eigener PRs, extern erkannte PRs
- Nachrichten – Nachrichten, Bereiche und der Fortschritt beim Bereitstellen eines Bereichs
- Tickets – Anlegen, Zuweisen, Neuzuweisen, Details, Status und die drei Endzustände
- Aufgaben – geordnete Lebenszyklus-Frames eines ausgeführten Laufs, damit Clients sie ordnen und Duplikate entfernen können
- Pipelines – nur Abschlussereignisse eines Laufs (abgeschlossen, abgebrochen, fehlgeschlagen)
- Beobachtbarkeit – Einträge im Aktivitätsprotokoll und Budgetschwellen
- Identität und Mitgliedschaft – Mitglied hinzugefügt, entfernt, Rolle geändert
- Kalender und Besprechungen – Ablauf der Authentifizierung, beginnende Besprechungen und abgeschlossene Aufnahmen
- Rigs – Übernahme, Zurückholen und unerwartetes Schließen
Gedächtnis, Orchestrierung, Plandokumente, Artefakte, Freigaben, der Eingang der Ticket-Synchronisierung, die Kalenderaktualisierung, Worktree-Merges, das Anlegen von Benutzern, Einladungen und der Widerruf von Geräten sind keine Domain-Ereignisse. Siehe die Referenz.
Den vollständigen Katalog, alle 53 konkreten Ereignisklassen, ihre Payloads und die 24 Abonnenten, die sie entgegennehmen, findest du in der Referenz der Domain-Ereignisse. Jene Seite ist das Inventar, diese hier das Modell.
Die Zugriffskontrolle zur Laufzeit hängt an zwei Mechanismen
Abschnitt betitelt „Die Zugriffskontrolle zur Laufzeit hängt an zwei Mechanismen“Ereignisse zu Mitgliedschaft und Geräten sehen symmetrisch aus. Sie sind es nicht, und das zählt, wenn du einschätzt, wie schnell ein Widerruf greift.
Der Widerruf eines Geräts beendet seine Sitzungen. Der Server beobachtet die Tabelle der gekoppelten Geräte und verwirft innerhalb von Sekunden jede laufende Sitzung, deren Gerät den aktiven Bestand verlassen hat.
Das Entfernen eines Mitglieds schließt den Socket nicht.
WorkspaceMemberRemoved wird entgegengenommen: LocalRpcServer und
RemoteRelayHost verwerfen die angehängten Arbeitsbereichsabonnements dieses
Benutzers, und RemoteEventForwarder macht seinen Mitgliedschafts-Cache
ungültig, sodass weitere Frames für diesen Arbeitsbereich nicht mehr
geschickt werden. Den nächsten RPC lehnt weiterhin die Rollenprüfung ab. Sie
löst die Mitgliedschaft bei jedem Aufruf neu auf, sodass die nächste
Anfrage mit “Not a member of this workspace” abgelehnt wird. Für alles, was
die Person versucht, gilt das sofort. Die Verbindung wird dafür nicht
aufgelegt.
Pipeline-Trigger
Abschnitt betitelt „Pipeline-Trigger“Pipeline-Trigger abonnieren Domain-Ereignisse und starten passende Pipelines
von selbst. PipelineTriggerDispatcher hört auf den ganzen Bus und dann:
- Bricht vorzeitig ab, wenn sich der Ereignistyp nicht auf einen Payload abbilden lässt
- Sucht aktivierte Trigger zu diesem Ereignistyp, über alle Arbeitsbereiche
- Grenzt jeden auf seinen eigenen Arbeitsbereich ein und wendet seinen Filter für die Payload-Übereinstimmung an
- Startet einen Lauf für jeden Trigger, der übrig bleibt
Die wichtige Einschränkung ist Schritt 1. Der Bus trägt 53 Ereignistypen. Die
Auswahl zum Hinzufügen eines Triggers startet einen Lauf für diese vierzehn
(Payload-Zweige von EventPayloadMapper):
ExternalPrDetected, PullRequestPublished, PullRequestStatusChanged,
PrMerged, MessageReceived, TicketAssigned,
TicketCompleted, TicketFailed, TicketCancelled,
BudgetThresholdCrossed, RepoAdded, MeetingRecordingStopped, SkillUpdated
und SpaceDeleted. Nichts anderes kann eine Pipeline starten.
Was ein Client davon sieht
Abschnitt betitelt „Was ein Client davon sieht“RemoteEventForwarder übersetzt die Ereignisse der Benachrichtigungsklasse in
Wire-Frames und schiebt sie per RPC an verbundene Sitzungen. Dort macht ein
Frame-Mapper daraus Benachrichtigungen in der App. Ein Thin Client sieht so
eine Projektion des Ereignisstroms auf dem Server und besitzt selbst keine
Ausführung. Darum geht es bei der
Aufteilung in den Thin Client.
Nicht jeder geschobene Frame ist eine Benachrichtigung. Der Strom zum Aufgaben-Lebenszyklus und die Ticket-Neuzuweisung gehen live an die Oberfläche. Im Benachrichtigungs-Feed stehen sie nicht, und sie lösen keinen Toast aus.
Siehe auch
Abschnitt betitelt „Siehe auch“- Pipelines und Automatisierung: was ein Trigger startet
- Tickets und Delegation: Zuweisung an einen Agenten oder an ein Team
- Architektur: wie Ereignisse in die Abhängigkeitsregel passen
- Referenz der Domain-Ereignisse: der vollständige Katalog und seine Abonnenten
- Pipeline-Trigger einrichten
- Benachrichtigungen konfigurieren