Was beweisen Tests zum erzwungenen Beenden über ein Agent-Gateway?
Tests zum erzwungenen Beenden zeigen, was ein Agent-Gateway nach einem Absturz belegen kann, von der Injektion von Zugangsdaten und Netzwerk-I/O bis zu dauerhaft gespeicherten Audit-Einträgen.

Ein Gateway, das Zugangsdaten für einen KI-Agenten verwaltet, muss auch dann sicher bleiben, wenn sein Prozess im denkbar ungünstigsten Moment verschwindet. Ein Test für den normalen Ablauf kann zeigen, dass eine Freigabe erscheint, eine Anfrage erfolgreich ist und anschließend ein Audit-Eintrag existiert. Er zeigt nicht, ob eine Zugangsdaten während einer unterbrochenen Anfrage nach außen gelangt ist oder ob das Audit-Log eine nie abgeschlossene Arbeit fälschlich als erledigt darstellt.
Tests zum erzwungenen Beenden machen die Lücken zwischen Aussagen wie «Anfrage gestartet», «Zugangsdaten angefügt», «entferntes System hat sie erhalten» und «der Eintrag ist dauerhaft gespeichert» sichtbar. Das sind voneinander getrennte Tatsachen. Wer sie als ein einziges Ereignis behandelt, liefert ein Aktions-Gateway aus, das kontrolliert wirkt, bis ein Absturz einen gewöhnlichen Wiederholungsversuch in ein doppeltes Deployment oder einen nicht nachvollziehbaren ausgehenden Aufruf verwandelt.
Bei einem macOS-Gateway musst du normales Beenden und den Tod des Prozesses unterscheiden. Apple beschreibt das normale Beenden einer App als Lebenszyklus, in dem die App ihren Zustand speichern und die Beendigungslogik ausführen kann. Eine erzwungene Beendigung gewährt diese Möglichkeit möglicherweise nicht. Apple nennt SIGKILL außerdem als Beendigungstyp, der auftreten kann, wenn ein Benutzer eine App zwangsweise beendet. Dein Testplan muss daher davon ausgehen, dass Aufräumhandler, verzögerte Schreibvorgänge und Telemetrie nach dem Best-Effort-Prinzip nicht ausgeführt werden.
Die nützliche Frage lautet nicht «Startet die App neu?». Sie lautet: Kannst du an jedem Unterbrechungspunkt genau sagen, welche Seiteneffekte möglich sind, welche ausgeschlossen sind und welche Belege erhalten bleiben?
Ein erzwungenes Beenden muss das Aufräumen unterbrechen
Ein Test zum erzwungenen Beenden ist nur dann aussagekräftig, wenn er dem Gateway keine Gelegenheit zum Aufräumen lässt. Wenn der Test eine höfliche Beendigungsfunktion aufruft, wartet, bis die Warteschlangen leer sind, Logs leert und erst danach beendet, hast du ein geordnetes Beenden getestet. Das ist wichtig, bildet aber nicht den Fehlerfall ab, der Sicherheitsteams beschäftigt.
Verwende zwei Beendigungsarten und benenne sie korrekt:
- Eine normale Beendigungsanfrage testet den Umgang mit Abbrüchen, das ordentliche Schließen von Dateien und die Darstellung einer unterbrochenen Sitzung in der Oberfläche.
- Ein harter Kill testet den Zustand von Speicher, Dateipuffern, offenen Sockets und laufender Arbeit, wenn keine Anwendungsbereinigung ausgeführt wird.
Unter macOS kann ein Test-Harness im ersten Fall kill -TERM und im zweiten kill -KILL verwenden. SIGTERM gibt einem Prozess die Möglichkeit, die Beendigung zu verarbeiten. SIGKILL tut das nicht. Bezeichne beide Fälle in der Ergebnistabelle nicht als «erzwungenes Beenden», denn sie beantworten unterschiedliche Fragen.
# Find the gateway process you started for the test.
pgrep -fl Sallyport
# Graceful termination case.
kill -TERM 48192
# Abrupt termination case.
kill -KILL 48192
# Confirm the process is gone.
ps -p 48192
# PID TTY TIME CMD
# 48192 ttys003 0:00.42 gateway-test
# After SIGKILL, ps should print no process row.
Die Prozess-ID ist nicht die Testkennung. Vergib für jeden Testlauf eine Lauf-ID, eine Aktions-ID und eine ID für die entfernte Anfrage. Trage diese IDs in die Aufzeichnungen des Fixtures und des Gateways ein. Ohne gemeinsame Kennungen wirst du Zeitstempel vergleichen und raten müssen, ob ein entfernter POST zu dem Lauf gehörte, den du beendet hast.
Teste niemals gegen einen Produktionsendpunkt, auch wenn der Aufruf deiner Ansicht nach harmlos ist. Der Zweck dieser Tests besteht darin, absichtlich mehrdeutige Ergebnisse zu erzeugen. Baue einen Empfänger, der vor der Annahme eines Bodys, nach dem Lesen der Header, nach dem Aufzeichnen des Bodys oder vor der Freigabe seiner Antwort pausieren kann. Eine echte Drittanbieter-API bietet diese Grenzen nicht zuverlässig und kann Wiederholungen oder Caching erzwingen, die du nicht vorgesehen hast.
Die Anfrage braucht klar definierte Unterbrechungspunkte
Du kannst einen Prozess nicht «während der Injektion von Zugangsdaten» beenden, wenn die Implementierung nicht festlegt, was das bedeutet. Füge rund um die Aktionspipeline beobachtbare Haltepunkte ein. Das sind Teststeuerungen, keine Richtlinie und kein Autorisierungsmechanismus für den Produktivbetrieb.
Für eine HTTP-Aktion eignet sich eine Abfolge wie diese:
- Das Gateway nimmt eine autorisierte Aktionsbeschreibung an und vergibt eine Aktions-ID.
- Es schreibt einen Absichts-Eintrag, falls das Design diesen vor Netzwerkaktivitäten verlangt.
- Es löst die Zugangsdaten innerhalb des geschützten Prozesses auf.
- Es erstellt die ausgehende Anfrage und fügt die Zugangsdaten ein.
- Es öffnet die Verbindung und schreibt die Anfrage.
- Es empfängt genug von der Antwort, um das Ergebnis auf der entfernten Seite einzuordnen.
- Es schreibt einen Abschluss- oder Eintrag mit unbekanntem Ergebnis und gibt erst dann ein Ergebnis an den Agenten zurück.
Setze nach jedem nummerierten Vorgang einen Haltepunkt. Dieser muss von einem separaten Prozess aus beobachtbar sein. Ein lokaler Socket nur für Tests, eine Named Pipe oder ein vom Harness gesteuerter Dateideskriptor sind geeignet. Ein Sleep-Aufruf ist weniger zuverlässig, weil Zeitabweichungen aus einem Grenztest einen Wettlauf machen.
Ein kompaktes Fixture-Protokoll kann so aussehen:
{
"action_id": "fq-2026-07-22-017",
"hold_after": "request_headers_built",
"release": false
}
Das Gateway pausiert, nachdem es die Header erstellt hat, aber bevor ein Verbindungsversuch beginnt. Das Harness bestätigt diesen Zustand, beendet den Prozess und fragt den Empfänger, ob er eine Verbindung gesehen hat. Das erwartete Ergebnis sind null eingehende Anfragen und null Header mit Zugangsdaten. Wenn der Empfänger an diesem Punkt eine Anfrage gesehen hat, liegt dein Prüfpunkt zu spät oder eine Hintergrundaufgabe hat die Grenze überschritten, ohne berücksichtigt zu werden.
Halte die Prüfpunkte eng. «Vor Netzwerk-I/O» ist zu ungenau, wenn DNS-Auflösung, Verbindungsaufbau, TLS-Aushandlung und Übertragung des Bodys in unterschiedlichen Aufgaben laufen. Du brauchst keinen Prüfpunkt innerhalb jedes Bibliotheksaufrufs. Du brauchst aber genug Struktur, um sagen zu können, ob der entfernte Server Zugangsdaten oder einen zustandsverändernden Body erhalten konnte.
Für SSH gilt dasselbe Prinzip, allerdings mit anderen Belegen. Pausiere, bevor sp-ssh eine verbindungsbezogene Anfrage mit Zugangsdaten erhält, nachdem der Helfer gestartet wurde, aber vor der Authentifizierung, nach der Authentifizierung, aber vor Beginn des Befehls, sowie nachdem der entfernte Befehl zurückgekehrt ist, aber bevor der lokale Abschluss gespeichert wird. Protokolliere Start und Ende des entfernten Befehls auf einem wegwerfbaren Test-Host. Leite die Ausführung eines Befehls nicht aus einer offenen TCP-Verbindung ab.
Ein Beenden vor der Injektion darf keine Spur hinterlassen
Der früheste Fehlerfall hat das klarste erwartete Ergebnis: Wenn das Gateway stirbt, bevor es Zugangsdaten angefügt oder den Transport gestartet hat, darf kein externer Dienst etwas von dieser Aktion sehen.
Das klingt offensichtlich, doch Implementierungen vermischen Vorbereitung und Versand häufig. Eine Client-Bibliothek kann eine Verbindung beginnen, während eine andere Aufgabe einen Header abruft oder formatiert. Ein Wiederholungs-Wrapper kann eine ausgehende Anfrage anlegen, bevor der Code den vorgesehenen Journal-Eintrag schreibt. Ein Metrik-Callback kann eine Aktionsbeschreibung mit einem URL-Query-Parameter schreiben, den dein normaler Redaktionspfad nie sieht.
Teste vier Abbrüche vor dem Versand:
- Nach der Autorisierung, aber vor jeder Abfrage von Zugangsdaten.
- Nach der Abfrage von Zugangsdaten, aber vor dem Erstellen der Anfrage.
- Nach dem Erstellen der Anfrage, aber bevor eine Socket-Verbindung beginnt.
- Nach Beginn des Verbindungsaufbaus, aber bevor Bytes mit Zugangsdaten den Prozess verlassen.
Jeder Abbruch braucht eine eigene Aussage. Vor der Abfrage von Zugangsdaten prüfst du Diagnoseausgaben und Logs auf das Fehlen von Werten oder Platzhaltern, die später ersetzt werden könnten. Nach der Abfrage prüfst du dieselben Ausgaben und stellst sicher, dass das Geheimnis die Prozessgrenze nie verlassen hat. Vor dem Verbindungsaufbau darf der Empfänger keinen Verbindungseintrag haben. Während des Verbindungsaufbaus kann er einen fehlgeschlagenen Handshake oder Verbindungsversuch sehen, darf aber weder einen Authorization-Header, ein Basic-Auth-Feld, einen benutzerdefinierten Zugangsdaten-Header noch einen SSH-Authentifizierungsversuch erhalten.
Diese Unterscheidung ist wichtig, denn ein Verbindungsversuch ist keine authentifizierte Aktion. Melde nicht «keine Aktion» wenn die entfernte Kante einen Verbindungsversuch aufgezeichnet hat. Die genaue Aussage lautet: Es wurden keine Zugangsdaten gesendet und keine Anfrage auf Anwendungsebene empfangen. Sicherheitsaufzeichnungen verlieren an Wert, wenn sie Belege glätten, die Betreiber später bei der Untersuchung eines Vorfalls benötigen.
Sallyports Design macht diese Grenze besonders prüfenswert: Der Agent soll niemals eine Klartext-Zugangsdaten halten, während die App selbst die HTTP- oder SSH-Aktion mit Zugangsdaten ausführt und ein Ergebnis zurückgibt. Der Test ist nicht abgeschlossen, nur weil der Agent das Geheimnis nicht besitzt. Er ist abgeschlossen, wenn ein beendetes Gateway eine halb vorbereitete Aktion ebenfalls nicht in eine ausgehende Anfrage mit Geheimnis verwandeln kann.
Injektion ist ein lokales Ereignis und kein Beweis für den Versand
Bei der Injektion von Zugangsdaten machen Teams den folgenschwersten Fehler in der Buchführung. Sie protokollieren «Zugangsdaten verwendet», sobald der Code einen Header erstellt oder eine Identität an eine SSH-Bibliothek übergibt. Das zeigt, dass das Gateway die Authentifizierung vorbereitet hat. Es beweist nicht, dass ein Kommunikationspartner die Daten erhalten hat.
Halte mindestens vier lokale Zustände getrennt:
| Zustand | Was du ehrlich behaupten kannst | Was du nicht behaupten kannst |
|---|---|---|
| Zugangsdaten aufgelöst | Der geschützte Prozess hat für diese Aktion Zugangsdaten gelesen | Ein Kommunikationspartner hat sie erhalten |
| Anfrage zusammengestellt | Der Prozess hat eine Anfrage mit Zugangsdaten im Speicher erstellt | Eine Verbindung wurde geöffnet |
| Transport-Schreibvorgang begonnen | Der Prozess hat versucht, Bytes zu senden | Die entfernte Anwendung hat sie verarbeitet |
| Ergebnis auf der entfernten Seite beobachtet | Der Prozess hat Belege von der entfernten Seite erhalten | Der Abschluss-Eintrag ist dauerhaft gespeichert |
Beende den Prozess einmal nach der Auflösung der Zugangsdaten und ein weiteres Mal, nachdem das Anfrageobjekt existiert, aber bevor der Transport-Schreibvorgang beginnt. In beiden Fällen darf der Agent kein Geheimnis erhalten, und das entfernte Fixture darf keine Anfrage mit Zugangsdaten aufzeichnen. Das Aktionsjournal sollte entweder einen unterbrochenen Vorbereitungszustand oder keinen dauerhaften Eintrag zeigen, je nachdem, wo deine Dauerhaftigkeitsgrenze liegt. Erzeuge keine abgeschlossene Aktion, nur damit das Journal ordentlich aussieht.
Beende den Prozess anschließend am ersten Punkt, an dem die Transportbibliothek schreiben kann. Das ist der schwierige Test. Der lokale Prozess kann eine Schreibfunktion aufgerufen haben, während Kernel, Proxy, TLS-Schicht oder entfernter Dienst die vollständige Anfrage möglicherweise noch nicht erhalten haben. Das erwartete Ergebnis sollte outcome=unknown sein, sofern der Empfänger keine positiven Belege dafür hat, dass die Anfrage angekommen ist oder nicht angekommen ist.
Protokolliere nicht die vollständigen Anfrage-Header, um diesen Test zu vereinfachen. Das würde einen zweiten Weg für Geheimnisse schaffen. Lass das Fixture stattdessen aus dem empfangenen Zugangsdatenwert eine nicht umkehrbare Testmarkierung berechnen und nur diese speichern. Das Gateway kann eine Referenz oder eine interne Kennung für die Zugangsdaten speichern. Vergleiche während des Tests Kennungen und Markierungen, ohne die Zugangsdaten selbst auszugeben.
Ein nützlicher Fixture-Eintrag kann so aussehen:
{
"action_id": "fq-2026-07-22-017",
"connection_seen": true,
"headers_complete": true,
"credential_marker": "sha256:7b8c...",
"body_complete": false,
"response_sent": false
}
Verwende Zugangsdaten nur für den Test, deren Wert außerhalb des Fixtures nirgends existiert. Halte sie trotzdem aus Screenshots, Shell-History und gewöhnlichen Logs heraus. Auch ein wegwerfbares Geheimnis bleibt ein geheimnisähnliches Objekt, und Testgewohnheiten gelangen leicht in Produktivcode.
Netzwerk-I/O erzeugt einen ehrlichen Zustand «unbekannt»
Sobald eine zustandsverändernde Anfrage den Rechner verlassen kann, endet die lokale Gewissheit, bevor das entfernte System unbedingt antwortet. Dieser Fall muss Wiederholungslogik, Formulierungen in der Oberfläche und die Bedeutung des Audit-Logs bestimmen.
Stell dir einen POST vor, der einen Deployment-Dienst zum Start eines Releases auffordert. Das Gateway schreibt die vollständige Anfrage. Der Dienst speichert den Deployment-Auftrag. Bevor die Antwort das Gateway erreicht, beendest du den Gateway-Prozess. Nach dem Neustart sind drei Wirklichkeiten möglich:
- Der Dienst hat die Anfrage nie erhalten.
- Der Dienst hat die Anfrage erhalten, aber abgelehnt.
- Der Dienst hat die Anfrage angenommen und ein Deployment erstellt.
Das lokale Gateway weiß möglicherweise nicht, welche Wirklichkeit eingetreten ist. Ein mit failed markierter Eintrag wäre in Fall drei falsch. Ein mit succeeded markierter Eintrag wäre in den Fällen eins und zwei falsch. Markiere ihn als unknown und bewahre Aktions-ID, ID der entfernten Anfrage, Ziel, Methode und den Zeitpunkt auf, an dem die lokale Beobachtung endete.
Hier richten blinde Wiederholungen Schaden an. Automatische Wiederholung ist beliebt, weil vorübergehende Netzwerkfehler häufig sind und erfolgreiche Demos reibungslos wirken. Bei einem GET ist eine Wiederholung meist vertretbar, sofern sie keine serverseitige Buchführung oder Rate-Limits beeinträchtigt. Bei einem POST, PATCH, entfernten Befehl oder einer schreibfähigen API-Anfrage braucht die Wiederholung eine Idempotenzmechanik oder einen späteren Abgleich.
Verwende die Idempotenzfunktion des entfernten Systems, falls es eine gibt. Sende ein für die Aktion bestimmtes Idempotenz-Token, nicht eines, das für die gesamte Agent-Sitzung wiederverwendet wird. Unterstützt die entfernte API keine Idempotenz, richte einen Abfrageweg ein, der vor einer Wiederholung feststellen kann, ob die Aktions-ID angenommen wurde. Gibt es beides nicht, soll ein Mensch entscheiden. Das ist weniger elegant als automatische Wiederherstellung, aber deutlich sicherer als eine doppelte Ausführung.
Teste mit deinem Empfänger genau diese Abfolge:
Gateway writes intent record
Gateway sends POST with action ID fq-2026-07-22-017
Receiver stores action ID and body
Receiver delays its HTTP response
Harness kills gateway with SIGKILL
Gateway restarts
Agent requests retry
Gateway checks receiver for action ID before another POST
Das Ergebnis sollte eine gespeicherte entfernte Aktion und einen lokalen Eintrag mit unterbrochenem oder unbekanntem Ergebnis zeigen, der später mit dem entfernten Zustand abgeglichen wird. Erscheint der zweite POST vor der Abfrage, hat der Test einen Fehler bei der Wiederholung gefunden. Überschreibt das Journal die Unsicherheit und lässt nur einen sauberen Erfolgseintrag stehen, hat es einen Audit-Fehler gefunden.
Verlasse dich nicht auf TCP-Schließereignisse als Beweis dafür, dass eine entfernte Anwendung nicht gehandelt hat. Ein Socket kann geschlossen werden, nachdem der Kommunikationspartner die Anfrage bereits an seinen Anwendungscode weitergegeben hat. Der dauerhafte Aktions-Eintrag des Empfängers ist der entscheidende Beleg.
Der Audit-Commit braucht ein klares Versprechen zur Dauerhaftigkeit
Ein Audit-Log wird nicht dadurch vertrauenswürdig, dass es eine Hashkette enthält. Eine Hashkette kann Änderungen oder Löschungen innerhalb der erhaltenen Sequenz sichtbar machen. Sie kann kein Ereignis zurückholen, das vor dem Tod des Prozesses nie dauerhaft gespeichert wurde.
Formuliere das Versprechen in einem Satz. Zum Beispiel: «Bevor ein Gateway eine zustandsverändernde externe Aktion beginnt, speichert es die Absicht dauerhaft. Nachdem es ein Ergebnis beobachtet hat, speichert es dieses Ergebnis dauerhaft, bevor es es an den Agenten zurückgibt.» Teste dann die beiden Verben «beginnt» und «dauerhaft», statt ein Objekt im Speicher mit Zeitstempel als Eintrag zu behandeln.
POSIX definiert fsync() als Aufforderung, die Daten einer Datei in den zugehörigen Speicher zu übertragen, und sagt, dass die Funktion erst zurückkehrt, wenn dieser Vorgang abgeschlossen ist oder einen Fehler meldet. Der Standard weist außerdem darauf hin, dass die Garantien des Speichers von Implementierung und Konfiguration abhängen. Das ist kein Grund, den Aufruf wegzulassen. Es bedeutet, dass du präzise festlegen und testen musst, was deine Software versprechen kann und wie sie sich bei der Wiederherstellung verhält.
Teste bei einem verschlüsselten, hashverketteten Log mindestens diese Unterbrechungen:
- Beenden nach dem Schreiben eines vorgeschlagenen Eintrags, aber vor der Dauerhaftigkeitsbarriere.
- Beenden nach der Dauerhaftigkeitsbarriere, aber vor der Aktualisierung des In-Memory-Index.
- Beenden, nachdem ein Abschluss-Eintrag dauerhaft gespeichert wurde, aber bevor der Agent die Antwort erhält.
- Beenden während Verdichtung, Rotation oder einer anderen Projektion des Journals.
Führe nach jedem Neustart den Offline-Verifizierungsbefehl aus und prüfe sowohl die rohe Audit-Sequenz als auch die für Benutzer sichtbaren Projektionen. Sallyport stellt sp audit verify bereit, um sein verschlüsseltes, hashverkettetes Audit-Log zu prüfen, ohne den Tresorschlüssel zu benötigen. Das macht den Befehl für diese Testreihe nützlich. Die Verifizierung sollte aber nur eine von mehreren Aussagen sein und nicht den gesamten Test ersetzen.
Die erwarteten Ergebnisse brauchen Differenzierung. Ein fehlender Eintrag nach einem Beenden vor der Dauerhaftigkeitsgrenze kann akzeptabel sein, wenn keine externe Aktion begonnen hat. Ein fehlender Eintrag, nachdem das Gateway eine zustandsverändernde Anfrage gestartet hat, ist nicht akzeptabel, wenn das Design eine Write-ahead-Absicht verspricht. Ein vorhandener Eintrag mit unbekanntem Ergebnis ist oft korrekt. Ein Eintrag, der einen Abschluss behauptet, bevor die entfernte Antwort beobachtet wurde, ist falsch, auch wenn der Test gewöhnlich zufällig besteht.
Halte den Verlauf eines Agent-Laufs getrennt vom Verlauf einzelner Aktionsaufrufe. Eine Sitzung kann abrupt enden, während mehrere Aktionen unterschiedliche Ergebnisse haben. Ein Eintrag auf Laufebene mit «beendet» ersetzt keine einzelnen Aufzeichnungen für eine Anfrage, die das entfernte System erreicht hat, und eine andere, die nie den Speicher verlassen hat.
Der Freigabestatus darf nicht über seinen Bezug hinaus bestehen
Ein Neustart testet die Autorisierung ebenso wie die Dauerhaftigkeit. Wenn ein Gateway einen bestimmten Agent-Prozess für eine Sitzung autorisiert, darf das Beenden diese Autorisierung nicht in eine wiederverwendbare Erlaubnis für einen neuen Prozess verwandeln, der zufällig eine ähnliche Anfrage stellt.
Die einfachste sichere Regel lautet: Eine Sitzungsfreigabe gehört zu einer beobachteten Prozessidentität und endet mit diesem Lauf. Nach einem Neustart braucht ein neuer Agent-Prozess eine neue Sitzungsautorisierung. Ein Prozess, der während des Neustarts des Gateways weiterlief, braucht ebenfalls eine neue Entscheidung, es sei denn, das Gateway kann die exakt gebundene Identität erneut herstellen und das Produkt dokumentiert dieses Verhalten ausdrücklich. Stelle eine Freigabe nicht aus einem losen Cache-Eintrag wie Befehlsname, Arbeitsverzeichnis oder einer benutzerfreundlichen Prozessbezeichnung wieder her.
Teste die Neustartgrenze mit zwei Agenten, die auf der Kommandozeile ähnlich aussehen, sich aber bei Signaturautorität oder Herkunft der ausführbaren Datei unterscheiden. Autorisiere den ersten. Beende das Gateway während einer Aktion. Starte es neu. Lass anschließend den zweiten Agenten dieselbe Aktion ausführen. Das Gateway muss eine neue Freigabeentscheidung anzeigen und darf die Sitzung des ersten Agenten nicht übernehmen.
Eine Freigabe pro Aufruf braucht einen anderen Test. Beende das Gateway, während die Freigabekarte sichtbar ist, starte es neu und wiederhole die Aktion. Das alte UI-Ereignis darf den neuen Aufruf nicht autorisieren. Beende das Gateway nach der Benutzerfreigabe, aber vor der Auflösung der Zugangsdaten, und stelle anschließend sicher, dass der neue Prozess die alte Freigabe nicht wiederverwenden kann. Diese Tests finden einen häufigen Fehler: den booleschen Wert «freigegeben» zu speichern, ohne ihn an eine Aktions-ID, eine bestimmte Sitzung und eine Ablaufbedingung zu binden.
Sallyports feste Schutzmechanismen geben diesem Test eine klare Form. Das Vault-Gate verweigert Aktionen bei gesperrtem Tresor, die Sitzungsautorisierung ist an einen neuen Agent-Prozess gebunden und ausgewählte Zugangsdaten können bei jeder Verwendung eine Freigabe verlangen. Tests zum erzwungenen Beenden sollten beweisen, dass diese Grenzen auch dann gelten, wenn Oberfläche, Tresorzustand und Aktionspipeline zu unterschiedlichen Zeitpunkten neu starten.
Erstelle vor der Testreihe eine Ergebnismatrix
Ein Test, der lediglich «Beenden in Phase X» sagt, lässt zu viel Raum für Interpretation. Erstelle eine Matrix mit Zeilen für Unterbrechungspunkte und Spalten für beobachtbare Ergebnisse. Prüfe das erwartete Ergebnis, bevor du den Testcode schreibst. Wenn sich das Team nicht einigen kann, was passieren soll, hat die Implementierung noch keinen definierten Fehlervertrag.
Verwende diese Spalten:
| Unterbrechungspunkt | Darf die entfernte Seite eine Verbindung sehen? | Darf die entfernte Seite Zugangsdaten sehen? | Zulässiger lokaler Aktionsstatus | Agent-Ergebnis nach der Wiederherstellung | Erforderliche Belege |
|---|---|---|---|---|---|
| Vor der Abfrage von Zugangsdaten | Nein | Nein | Nicht gestartet oder unterbrochen | Neue Freigabe oder Wiederholungspfad | Nur Gateway-Trace |
| Nach der Auflösung der Zugangsdaten | Nein | Nein | Unterbrochene Vorbereitung | Neue Freigabe oder Wiederholungspfad | Nur Gateway-Trace |
| Während des Schreibens der Anfrage | Ja | Möglicherweise | Unbekannt | Vor der Wiederholung abgleichen | Empfänger- und lokaler Eintrag |
| Nach der Annahme durch die entfernte Seite | Ja | Ja | Unbekannt, bis beobachtet oder abgeglichen | Vor der Wiederholung abgleichen | Dauerhafter Eintrag der entfernten Seite |
| Nach dauerhaft gespeichertem Abschluss | Ja | Ja | Abgeschlossen | Zwischengespeichertes oder abgeglichenes Ergebnis zurückgeben | Verifizierter Audit-Eintrag |
Die Wörter «möglicherweise» und «unbekannt» sind keine Schwächen. Sie beschreiben verteilte Arbeit ehrlich. Das gefährliche Wort ist «fehlgeschlagen», wenn das Gateway keine Belege dafür hat, dass der entfernte Dienst nicht gehandelt hat.
Führe jede Zeile wiederholt aus, aber ersetze Kontrolle nicht durch bloße Wiederholung. Einhundert zufällige Beendigungen können die Grenze zwischen einem Journal-Anhang und seiner Dauerhaftigkeitsbarriere verfehlen. Ein einziger kontrollierter Abbruch an einem Haltepunkt kann zeigen, wie diese Grenze funktioniert. Wiederhole den Test anschließend, um Wettläufe, Scheduling-Fehler und versehentliche Verschiebungen des Prüfpunkts zu erkennen.
Sammle bei jedem Lauf Artefakte von beiden Seiten: die Ereigniszeitleiste des Harness, die dauerhafte Aktionsliste des entfernten Fixtures, Informationen zum Prozessende, Diagnoseausgaben bei der Wiederherstellung des Gateways, die Ausgabe der Audit-Verifizierung und die für den Agenten sichtbare Ausgabe. Verwende die Lauf-ID im Dateinamen. Wenn ein Test fehlschlägt, sichere die Belege vor einem erneuten Lauf. Der zweite Lauf zerstört häufig den einzigen brauchbaren Hinweis.
Behandle Abweichungen als Designarbeit und nicht als Testgeräusch
Wenn ein Test zum erzwungenen Beenden eine Abweichung zwischen Gateway-Journal und entferntem Fixture ergibt, solltest du die Assertion nicht einfach anpassen, bis sie besteht. Die Abweichung ist meist das eigentliche Testergebnis.
Meldet das Fixture eine angenommene Anfrage, während das Gateway keine Absicht protokolliert, musst du die dauerhafte Absichtsgrenze nach vorne verschieben oder die Aktion vor dieser Grenze stoppen. Meldet das Gateway einen Abschluss, während das Fixture keine Aktion kennt, musst du feststellen, ob das Gateway einen lokalen Schreibvorgang mit einem entfernten Ergebnis verwechselt hat. Kann ein neu gestarteter Agent ohne neue Freigabe handeln, musst du die Identitätsbindung korrigieren, statt nur das Timeout zu verlängern.
Das beste Ergebnis ist kein Dashboard voller grüner Tests. Es ist ein Fehlervertrag, den ein Betreiber unter Druck verwenden kann: Diese Aktion hat den Rechner sicher nicht verlassen. Diese Aktion hat das entfernte System möglicherweise erreicht und muss abgeglichen werden. Diese Aktion wurde abgeschlossen und ihr Eintrag hat die Verifizierung überstanden. Nur diese Kategorien machen eine Entscheidung nach einem Absturz belastbar.
Führe diese Testreihe immer aus, wenn du die Verwaltung von Zugangsdaten, Transportbibliotheken, Journaling, Wiederholungsverhalten, Prozessüberwachung oder Freigaben änderst. Ein Gateway verdient Vertrauen, indem es sich vorhersehbar verhält, wenn es keine Gelegenheit mehr bekommt, sich zu erklären.
FAQ
Was ist der Unterschied zwischen dem normalen und dem erzwungenen Beenden eines Agent-Gateways?
Beim normalen Beenden hat der Prozess Zeit, Aufräumcode auszuführen, Puffer zu leeren und offene Arbeit abzuschließen. Ein erzwungenes Beenden ist nützlich, weil diese Möglichkeit entfällt. Teste beides, aber behandle das Ergebnis der erzwungenen Beendigung als maßgebliche Fehlergrenze.
Reicht das Abbrechen einer Anfrage aus, um die Absturzsicherheit eines Gateways zu testen?
Nein. Eine abgebrochene Anfrage zeigt nur, dass dein Client einen normalen Abbruchpfad verarbeiten kann. Ein beendetes Gateway zeigt, ob Zugangsdaten, Audit-Einträge, laufende Verbindungen und Freigaben sicher bleiben, wenn der Prozess keine Gelegenheit zum Aufräumen erhält.
Was soll passieren, wenn das Gateway vor der Injektion von Zugangsdaten abstürzt?
Beende das Gateway, nachdem die Anfrage angenommen wurde, aber bevor es eine Zugangsdaten auswählt oder liest. Das erwartete Ergebnis ist eindeutig: keine ausgehende Verbindung, kein aus Zugangsdaten abgeleiteter Header und ein Audit-Eintrag, der einen unterbrochenen Versuch beschreibt, falls das Design zu diesem Zeitpunkt Versuche protokolliert.
Wie sollte ein Agent-Gateway mit einem Absturz während der Netzwerkkommunikation umgehen?
Das Gateway sollte eine abgeschlossene Aktion nur dann melden, wenn dauerhafte Belege für das behauptete Ergebnis vorliegen. Wenn das entfernte System die Anfrage möglicherweise erhalten hat, das Gateway aber die Antwort verloren hat, muss das Ergebnis als unbekannt protokolliert werden. Anschließend muss ein Betreiber es mit dem entfernten System abgleichen.
Sollte ein Agent rohe HTTP-Fehler nach einer fehlgeschlagenen Anfrage erhalten?
Nein. Ein Antwort-Body kann Geheimnisse, personenbezogene Daten, Tokens oder technische Details enthalten, die ein Agent nicht benötigt. Gib nur das kleinste Ergebnis zurück, mit dem der Agent weiterarbeiten kann, und halte Transportdiagnosen aus der normalen Agentenausgabe heraus.
Was ist der Unterschied zwischen einem Absichts- und einem Abschluss-Eintrag?
Ein Write-ahead-Eintrag ist eine dauerhaft gespeicherte Absicht, die vor Beginn eines Seiteneffekts aufgezeichnet wird. Ein Abschluss-Eintrag belegt das beobachtete Ergebnis nach dem Seiteneffekt. Werden beide in umgekehrter Reihenfolge geschrieben, kann ein Absturz ein Audit-Log hinterlassen, dessen Geschichte nicht zum Netzwerkgeschehen passt.
Kann ein Agent nach einem erzwungenen Beenden des Gateways sicher erneut versuchen?
Nein. Ein blindes Wiederholen nach einem unterbrochenen POST kann zwei Tickets, zwei Abbuchungen, zwei Deployments oder zwei zerstörerische Änderungen erzeugen. Wiederhole die Aktion nur, wenn die entfernte API Idempotenz unterstützt, der Vorgang von Natur aus idempotent ist oder ein Betreiber das unbekannte Ergebnis geklärt hat.
Wie richte ich eine sichere Umgebung für Tests zum erzwungenen Beenden ein?
Verwende einen Server, den du kontrollierst, oder ein HTTP-Test-Fixture, das Verbindungszeit, Header, Body-Empfang und das Freigeben der Antwort protokolliert. Füge einen Haltepunkt ein, damit die Anfrage in jeder Phase pausieren kann. Beende das Gateway anschließend aus einer separaten Shell, während der Haltepunkt aktiv ist.
Was soll mit Freigaben passieren, wenn das Gateway neu startet?
Die Freigabe sollte mit dem Agent-Prozess oder der Sitzung ablaufen und nicht allein deshalb bestehen bleiben, weil das Gateway neu gestartet wurde. Ein Neustart darf einen unterbrochenen Lauf nicht in einen stillschweigend autorisierten neuen Lauf verwandeln. Wenn sich die Identitätsgrenze geändert hat, ist eine neue Sitzungsentscheidung erforderlich.
Beweist ein hashverkettetes Audit-Log, dass keine Aktion verloren gegangen ist?
Es zeigt, dass das Gateway Manipulationen an der noch auf der Festplatte vorhandenen Audit-Sequenz erkennen kann. Es beweist nicht, dass jeder gestartete Vorgang vor einem abrupten Beenden dauerhaft gespeichert wurde. Dafür brauchst du weiterhin kontrollierte Unterbrechungstests und Belege von der entfernten Seite.