# OpenAPI-Agent-Aktionen sicher und zuverlässig entwerfen

Ein OpenAPI-Dokument kann einem Agenten erklären, wie er einen Endpunkt aufruft. Es kann ihm jedoch nicht von selbst sagen, was ein Aufruf bedeuten darf, wann ein Mensch eingreifen muss oder wie der Agent nach einem unklaren Fehler reagieren soll. Jede dokumentierte Operation als Agent-Aktion zu behandeln, führt zu Tools, die in einer Demo vollständig wirken und im Alltag gefährlich werden.

Eine brauchbare Aktion ist kleiner als ein Endpunkt. Sie verfolgt einen klar begrenzten Zweck, nimmt Eingaben an, die der Agent begründen kann, liefert ein Ergebnis, mit dem der Agent weiterarbeiten kann, verknüpft die Freigabe mit der möglichen Wirkung und enthält einen ausdrücklichen Plan für Fehler. Erledige diese Arbeit, bevor du eine Operation mit einem Agenten verbindest. Nach der ersten doppelten Abbuchung, der versehentlichen Änderung in der Produktionsumgebung oder dem geleakten Token nachzurüsten, ist eine besonders schmerzhafte Art, die Lektion zu lernen.

## Eine Operation ist noch keine Agent-Aktion

Ein HTTP-Endpunkt, eine OpenAPI-Operation und eine Agent-Aktion beantworten unterschiedliche Fragen. Sie werden oft vermischt, weil eine OpenAPI-Operation einen bequemen Ausgangspunkt bietet. Die Unterschiede entscheiden aber darüber, ob die Automatisierung verständlich bleibt.

Ein Endpunkt ist eine Adresse wie `/v1/deployments`. Eine Operation ergänzt die HTTP-Methode. Deshalb unterscheiden sich `POST /v1/deployments` und `GET /v1/deployments`. Eine Agent-Aktion ergänzt den menschlichen und betrieblichen Vertrag: Welches Ziel verfolgt sie, welche Argumente akzeptiert sie, welche Auswirkungen kann sie haben, welche Nachweise gelten als Erfolg und wer muss zustimmen?

Die OpenAPI Specification definiert ein Operation Object mit Feldern wie `operationId`, `parameters`, `requestBody`, `responses` und `security`. Verwende diese Felder als Hinweise, nicht als automatische Checkliste für die Veröffentlichung. Eine Operation mit vollständig beschriebenem Schema kann trotzdem eine schlechte Agent-Aktion sein, wenn ihre Beschreibung eine Wirkung in der Produktionsumgebung hinter einem harmlos klingenden Namen verbirgt.

Betrachte diese beiden Operationen:

```text
GET  /v1/projects/{project_id}/builds/{build_id}
POST /v1/projects/{project_id}/builds/{build_id}/promote
```

Die erste ruft einen Datensatz ab. Die zweite kann Datenverkehr umleiten, Artefakte veröffentlichen oder einen Release-Kanal ändern. Die Route deutet den Unterschied nur an. Das Design der Aktion muss ihn ausdrücklich benennen.

Ich habe Teams gesehen, die ein allgemeines `request`-Tool bereitstellten, weil ihre API bereits über eine saubere OpenAPI-Datei verfügte. Der Agent durfte daraufhin beliebige Pfade, Query-Strings und Bodies zusammenstellen. Das ist kein Aktionskatalog. Es ist Remote-Code-Ausführung gegen eine Geschäfts-API, nur mit besserer Zeichensetzung.

Veröffentliche eine Operation erst, wenn du einen Satz in dieser Form schreiben kannst: «Diese Aktion [tut etwas Bestimmtes] an [einem klar begrenzten Objekt] und gibt [einen Nachweis über den daraus entstandenen Zustand] zurück.» Wenn du dafür unklare Verben wie «verwalten», «verarbeiten» oder «behandeln» brauchst, ist die Aktion noch zu breit.

## Beginne mit der Wirkung, nicht mit dem Anfrage-Schema

Die Freigabe sollte sich nach der Wirkung eines Aufrufs richten, nicht nach seinem HTTP-Verb oder dem scheinbar einfachen JSON-Body. Ein kleines `POST` kann eine unumkehrbare Verpflichtung erzeugen. Ein ausführliches `GET` kann private Daten offenlegen. Ein `DELETE` entfernt vielleicht nur einen entbehrlichen Entwurf, während ein `PATCH` den Zugriff aller anderen widerrufen kann.

Beschreibe die Wirkung, bevor du die Felder prüfst, in Begriffen, die eine für das System verantwortliche Person sofort versteht. Frage, was sich ändert, wenn der Server den Aufruf zweimal ausführt, auf das falsche Objekt anwendet oder erst fünf Minuten später als vom Agenten beabsichtigt ausführt. Diese Fragen trennen routinemäßiges Abrufen von einer Aktion, die geprüft werden muss.

Bei der Prüfung einer möglichen Operation verwende ich vier Wirkungsklassen:

- Beobachtung: Ruft begrenzte Informationen ab und verändert nichts auf dem Server.
- Umkehrbare Änderung: Erstellt, aktualisiert oder entfernt etwas, für das es einen dokumentierten und praktisch nutzbaren Rückgängig-Weg gibt.
- Externe Verpflichtung: Sendet eine Nachricht, startet einen kostenpflichtigen Vorgang, veröffentlicht Material oder ändert einen für Kunden sichtbaren Zustand.
- Unumkehrbare oder weitreichende Änderung: Löscht Datensätze dauerhaft, erneuert Zugangsdaten, ändert Berechtigungen oder betrifft viele Objekte.

Diese Klassen sind kein Berechtigungsmodell. Sie erzwingen ehrliche Beschreibungen. Eine Operation «Rechnung erstellen» gehört zur externen Verpflichtung, auch wenn die Anfrage nur zwei Felder enthält. Eine Operation «Umgebung neu starten» kann zu einer weitreichenden Änderung werden, wenn eine Umgebung viele Dienste enthält.

Leite Sicherheit nicht aus dem Methodennamen ab. HTTP definiert `GET` im Protokollsinn als sicher. Das bedeutet, dass der Client darüber keine Zustandsänderung anfordern sollte. Es ist eine Konvention und kein Beweis dafür, dass sich ein bestimmter Server daran hält. Ich bin Diagnose-Endpunkten begegnet, die beim wiederholten Aufruf Caches aktualisierten, die Erstellung von Berichten auslösten und knappe Kapazitäten verbrauchten. Teste das tatsächliche Verhalten, nicht das, was das Verb vermuten lässt.

Trenne außerdem die Wirkung einer Aktion von der Empfindlichkeit ihres Ergebnisses. Einen Zugriffstoken abzurufen ist vielleicht schreibgeschützt, aber seine Rückgabe an den Agenten macht die Kontrolle des Aufrufs zunichte. Ein privater Kundendatensatz kann eine Freigabe erfordern, auch wenn die API kein einziges Byte verändert.

Eine gute Aktionskarte hält beide Dimensionen in verständlicher Sprache fest:

```text
Aktion: promote_preview_build
Wirkung: Ändert einen benannten Preview-Build in den Staging-Release-Kanal.
Umfang: Ein Projekt und eine Build-ID.
Ergebnis: Release-ID, resultierender Kanal und Zeitstempel des Servers.
Menschliche Zustimmung: Bei jedem Aufruf erforderlich.
Wiederholung: Nie automatisch wiederholen, außer der Server akzeptiert dasselbe Idempotenz-Token.
```

Diese Karte macht oft fehlende API-Semantik sichtbar, bevor ein Agent auch nur eine Codezeile ausführt. Wenn niemand sagen kann, ob eine Wiederholung sicher ist, ist die Aktion noch nicht bereit.

## Eingaben brauchen Grenzen, über die ein Agent nicht hinwegreden kann

Eine Agent-Aktion braucht oft einen kleineren Eingabevertrag, als der Endpunkt akzeptiert. OpenAPI-Schemata definieren Typen und Strukturen. Ein Agent braucht zusätzlich Einschränkungen, die verhindern, dass er eine Aufgabe durch kreative Argumente ausweitet.

Nimm eine Operation zum Erstellen einer Bereitstellung. Die unveränderte API unterstützt vielleicht viele Optionen für interne Clients: Umgebung, Artefaktverweis, Region, Replikazahl, Umgebungsvariablen, Feature-Schalter, Labels und ein frei konfigurierbares Objekt. Wenn du dem Agenten jedes Feld gibst, machst du aus einer einfachen Anfrage eine unkontrolliert zugängliche Administrationsoberfläche.

Erstelle eine Aktion mit Eingaben, die zur Aufgabe passen. Wenn die Aufgabe lautet «Stelle den Build, der die Tests bestanden hat, in einer Preview-Umgebung bereit», braucht der Agent vielleicht nur `project_id`, `build_id` und einen kurzen `reason`. Der Executor wählt die erlaubte Umgebung und weist alles zurück, was außerhalb des Aktionsumfangs liegt.

Diese Anfrageform macht die Grenze konkret:

```json
{
  "project_id": "proj_4821",
  "build_id": "build_9017",
  "reason": "Preview requested after integration tests passed"
}
```

Füge `target_url`, beliebige `headers`, einen rohen Request-Body oder ein allgemeines `options`-Objekt nicht bloß deshalb hinzu, weil der zugrunde liegende Endpunkt sie unterstützt. Jede solche Ausweichmöglichkeit verwandelt deine sorgfältig benannte Aktion wieder in einen generischen Client.

Nutze die OpenAPI-Felder, die bereits nützliche Grenzen enthalten. Setze `additionalProperties: false`, wenn ein Objekt nur benannte Felder akzeptieren soll. Verwende `enum` für eine tatsächlich kleine Auswahl erlaubter Werte. Lege Längen- und Musterbeschränkungen fest, wenn IDs einem etablierten Format folgen. Markiere Felder als erforderlich, wenn der Executor sie nicht sicher ableiten kann.

Dieses Fragment weist nicht geprüfte Konfigurationsfelder zurück und macht den vorgesehenen Umfang im Schema sichtbar:

```yaml
DeployPreviewRequest:
  type: object
  additionalProperties: false
  required:
    - project_id
    - build_id
    - reason
  properties:
    project_id:
      type: string
      pattern: '^proj_[A-Za-z0-9]+$'
    build_id:
      type: string
      pattern: '^build_[A-Za-z0-9]+$'
    reason:
      type: string
      minLength: 8
      maxLength: 240
```

`additionalProperties: false` verhindert einen typischen Fehler: Ein Agent lernt aus einem Beispiel einer anderen API, dass er `environment_variables` senden kann, legt Geheimnisse oder unsichere Überschreibungen in diesem Feld ab und der Server akzeptiert sie stillschweigend. Die Zurückweisung des Feldes liefert dem Agenten einen brauchbaren Fehler statt einer überraschenden Bereitstellung.

Schemata ersetzen keine Autorisierung auf Objektebene. Eine gültige `project_id` kann trotzdem auf ein Projekt außerhalb der Aufgabe verweisen. Der Executor muss prüfen, ob das angeforderte Objekt zum erlaubten Konto, Workspace, Repository oder zur erlaubten Umgebung gehört. Führe diese Prüfung nahe am Aktions-Executor durch, damit sie nicht von der Erklärung des Agenten abhängt.

Freitext braucht besondere Behandlung. Ein Begründungsfeld kann einem Prüfer helfen, darf aber niemals zu einem Befehlskanal für den Executor werden. Speichere den Text als Audit-Anmerkung. Verarbeite ihn nicht als Befehle, Ressourcenauswahl oder Ausnahme von Berechtigungen.

## Erwartete Ergebnisse müssen die nächste Entscheidung ermöglichen

Ein Agent braucht ein Ergebnis, das er beurteilen kann, nicht eine rohe HTTP-Antwort, die vollständig in seinen Kontext gekippt wird. Jeder Header, jedes Debug-Feld und jedes verschachtelte Objekt erhöht die Verwirrung und kann Daten offenlegen, die der Agent für seine Aufgabe nicht braucht.

Definiere den Erfolg in fachlichen Begriffen, bevor du Antwortcodes auswählst. Bei einer Bereitstellungsaktion sollte das Ergebnis die Bereitstellung, ihren Zustand und den Ort nennen, an dem der Server den weiteren Fortschritt meldet. Bei einer Datensatzänderung sollte es den Datensatz identifizieren und die geänderten Felder bestätigen. Bei einer Löschung sollte es das Ziel und die verbleibende Möglichkeit zur Wiederherstellung nennen.

Ein kompaktes Ergebnis für eine asynchrone Operation kann so aussehen:

```json
{
  "status": "accepted",
  "deployment_id": "dep_2388",
  "project_id": "proj_4821",
  "build_id": "build_9017",
  "target": "preview",
  "operation_status": "queued"
}
```

Diese Antwort sagt etwas Genaues: Der Server hat die Arbeit angenommen, aber die Bereitstellung ist noch nicht abgeschlossen. Ein Agent darf nach dieser Antwort nicht «bereitgestellt» melden. Er sollte entweder eine separate schreibgeschützte Statusaktion verwenden oder dem Nutzer sagen, dass der Vorgang in der Warteschlange steht.

Hier führen viele OpenAPI-Dokumente Agenten in die Irre. Eine `202 Accepted`-Antwort bedeutet, dass der Server die Anfrage zur Verarbeitung angenommen hat. Die Verarbeitung muss zu diesem Zeitpunkt noch nicht begonnen oder abgeschlossen sein. `202` wie einen Erfolg im selben Sinn wie ein abgeschlossenes `200` zu behandeln, erzeugt falsche Aussagen in Logs und Benachrichtigungen an Nutzer.

Trenne das Transportergebnis vom Ergebnis der Aktion. Ein HTTP-`200` kann einen fachlichen Fehler enthalten, etwa `{\"state\":\"rejected\",\"reason\":\"build is not eligible\"}`. Umgekehrt kann `409 Conflict` dem Agenten sagen, dass der gewünschte Zustand bereits existiert. Die Aktionshülle sollte solche Fälle in wenige eindeutige Zustände übersetzen, etwa `completed`, `pending`, `already_in_desired_state`, `rejected` und `unknown`.

Versprich keine falsche Einheitlichkeit. Manche APIs geben nur eine undurchsichtige Job-ID zurück. Das ist in Ordnung, wenn du eine Statusaktion anbietest, die sie auflösen kann. Der Fehler besteht darin, die Lücke zu verbergen. Sage genau, was der erste Aufruf feststellt und was nicht.

Filtere Fehlerdetails, bevor sie den Agenten erreichen. Ein Serverfehler kann interne URLs, Autorisierungs-Header, Stacktraces oder Daten eines anderen Nutzers enthalten. Der Agent braucht einen Grund, mit dem er handeln kann, etwa «Build-ID gehört nicht zur Projekt-ID», sowie eine sichere Korrelations-ID für die menschliche Untersuchung. Die Fehlerseite des Upstream-Systems braucht er nicht.

## Die Freigabe gehört an den Punkt der Verpflichtung

Fordere eine Freigabe an, wenn ein Aufruf eine bedeutsame Verpflichtung erzeugen kann, und beschreibe im Freigabefenster das Objekt und die Wirkung. Wer einmal pauschal um zukünftige Befugnisse bittet, trainiert Menschen darauf, Warnungen wegzuklicken, die sie nicht beurteilen können.

Sitzungsfreigabe und Freigabe einzelner Aufrufe lösen unterschiedliche Probleme. Eine Sitzungsfreigabe sagt: «Ich erkenne diesen Agent-Prozess und erlaube ihm während seiner Laufzeit diese Aktionsgruppe.» Eine Aufruffreigabe sagt: «Ich genehmige jetzt genau diese folgenschwere Anfrage.» Ersetze das eine nicht durch das andere.

Ein Agent, der den Build-Status prüfen kann, darf eine Stunde lang laufen, ohne jemanden zu stören. Ein Agent, der einen Build hochstuft, sollte im Moment der Zustimmung Projekt, Build-ID, Release-Kanal und Begründung anzeigen. So kann ein Prüfer die Anfrage beurteilen. «Bereitstellungstool erlauben» liefert dafür kaum Informationen.

Verwende ein Freigabefenster nicht als Ersatz für Eingabevalidierung. Wenn eine Aktion beliebige Ziele oder beliebige Berechtigungsumfänge zulässt, muss ein Prüfer unter Zeitdruck eine große, wechselhafte Nutzlast entziffern. Begrenze zuerst die Eingaben. Danach bestätigt die Freigabe eine klar abgegrenzte Aktion.

Die richtige Häufigkeit hängt von der Wirkung ab. Fordere bei jeder Ausführung eine Freigabe an, wenn die Aktion veröffentlicht, Zugriffsrechte ändert, eine externe Zahlung anstößt oder einen großen Produktionsumfang betrifft. Eine Sitzungszustimmung kann für eine Gruppe schreibgeschützter Aufrufe oder eng begrenzter, umkehrbarer Änderungen passen, aber erst, wenn Prozessidentität und Aktionskatalog für den Prüfer sichtbar sind.

Sallyport unterscheidet diese Fälle mit einer Sitzungsautorisierung für einen erstmals erkannten Agent-Prozess und einer optionalen Freigabe bei jeder Verwendung eines bestimmten Zugangsschlüssels. Die Tresorsperre verweigert außerdem alle Aktionen, solange der Tresor gesperrt ist. Eine Freigabe kann dadurch keinen gesperrten Geheimnisspeicher versehentlich umgehen.

Lass Menschen keine Fehler freigeben, die Software verhindern kann. Wenn ein Build nicht für eine Hochstufung geeignet ist, sollte der Executor ihn vor der Freigabe ablehnen. Freigabefenster sind für echte Entscheidungen da, nicht dafür, dass ein müder Prüfer einen fehlerhaften Zustand entdeckt.

## Ein Timeout erzeugt einen unbekannten Zustand, keine Anweisung zur Wiederholung

Ein Netzwerk-Timeout nach einer verändernden Anfrage legt schlampiges Design von Agent-Aktionen offen. Der Agent hat die Anfrage gesendet und dann die Antwort verloren. Der Server hat vielleicht nichts getan, die Änderung abgeschlossen oder verarbeitet sie noch. Der Agent kann die Wahrheit nicht dadurch ermitteln, dass er seine bevorzugte Antwort annimmt.

Betrachte einen typischen Fehler. Ein Agent ruft `POST /v1/invoices` mit Kunde, Betrag und einer Zeitüberschreitung auf. Die Verbindung bricht ab, nachdem der Server die Rechnung erstellt, aber bevor er die Antwort gesendet hat. Der Agent sieht einen Timeout, wiederholt die Anfrage mit denselben Daten und der Server erstellt eine zweite Rechnung. Im Audit-Log steht nun, dass der Agent seine Wiederholungsrichtlinie befolgt hat. Das stimmt technisch, hilft im Betrieb aber nicht weiter.

Ein Idempotenz-Token behebt das nur, wenn der Server es tatsächlich unterstützt. Der Client erzeugt pro beabsichtigter Aktion einmal ein Token, sendet es mit der ersten Anfrage und verwendet bei einer Wiederholung exakt dasselbe Token. Der Server muss das Token an die ursprüngliche Anfrage binden und das ursprüngliche Ergebnis oder ein kompatibles Konfliktergebnis zurückgeben, statt die Wirkung erneut auszuführen.

```text
Idempotency-Key: act_01HZX7FQ2Z9K8M6R4T3V1W0Y
```

Die Aktionshülle muss dieses Token der Improvisation des Agenten entziehen. Erzeuge es erst bei der Ausführung, speichere es mit dem Aktionsversuch und verwende es nur für diesen Versuch erneut. Ein vom Agenten geliefertes Token kann kollidieren, für unabhängige Anfragen wiederverwendet werden oder zu einer weiteren Angriffsfläche für Prompt-Injection werden.

Wenn die API keine dokumentierte Idempotenzsemantik besitzt, wiederhole eine verändernde Operation nach einem Timeout nicht automatisch. Gib `unknown` mit der Aktions-ID zurück und biete eine schreibgeschützte Suchaktion an, die den Zustand auf dem Server prüfen kann. Gibt es keine solche Suche, muss ein Mensch ermitteln, was passiert ist, bevor jemand die Anfrage wiederholt. Diese Antwort wirkt unbequem, weil die Situation unbequem ist. Vorgetäuschte Gewissheit verbessert sie nicht.

OpenAPI kann einen Header-Parameter namens `Idempotency-Key` dokumentieren. Die Dokumentation allein garantiert jedoch kein Serververhalten. Teste es gezielt: Sende dasselbe Token zweimal mit derselben Nutzlast und anschließend dasselbe Token mit einer geänderten Nutzlast. Das Serververhalten sollte das erste Paar zusammenführen und die geänderte Anfrage ablehnen oder eindeutig behandeln. Führt es still beide Änderungen aus, ist der Header nur Dekoration.

Andere Fehler brauchen eigene Regeln. Behandle `401` und `403` als Stoppsignal, nicht als Aufforderung, nach anderen Zugangsdaten zu suchen. Behandle `429` nur dann als Wartefall, wenn die API eine Verzögerung für Wiederholungen mitteilt oder deine Aktion über eine begrenzte Backoff-Regel verfügt. Behandle Validierungsfehler als nutzbares Feedback, wenn der Fehler eine erlaubte Korrektur nennt.

## Authentifizierung verleiht einem Agenten kein Urteilsvermögen

Eine OpenAPI-`security`-Deklaration beschreibt, wie ein Client seine Identität gegenüber einer API nachweist. Sie sagt nicht, ob ein Agent die Operation aufrufen sollte, ob er ein bestimmtes Zugangsmittel für ein bestimmtes Objekt verwenden darf oder ob ein Mensch die Wirkung prüfen muss.

Das Security Requirement Object der Specification verknüpft eine Operation mit benannten Sicherheitsschemata. Ein Bearer-Schema kann einem Client sagen, einen Autorisierungs-Header zu senden. Basic Authentication kann erklären, wie ein Zugangsdaten-Header aufgebaut wird. Das ist Transport-Authentifizierung. Lies nicht mehr hinein.

Halte vier Fragen getrennt:

- Wer oder was ruft diese Aktion auf?
- Welche Zugangsdaten verwendet der Executor bei der Upstream-API?
- Welche Objekte und Wirkungen erlauben diese Zugangsdaten?
- Welche Aktionsversuche gibt ein Mensch frei?

Wenn Teams diese Fragen vermischen, übergeben sie dem Agenten meist ein Token und nennen das Autorisierung. Das Token erscheint dann in Tool-Ausgaben, Shell-Verläufen, Debug-Logs, Prompts oder Konfigurationsdateien. Es zu widerrufen wird zu einem Bereinigungsprojekt statt zu einer einzelnen Aktion.

Die sicherere Struktur hält die Zugangsdaten im Executor. Der Agent liefert begrenzte Aktionseingaben. Der Executor wählt ein zulässiges Zugangsmittel, fügt es in die HTTP-Anfrage ein, wertet die Antwort aus und gibt das gefilterte Ergebnis zurück. Der Agent braucht keinen Klartextzugriff auf einen API-Schlüssel, um eine Aktion anzufordern.

Für SSH gilt dieselbe Regel. Ein Agent muss vielleicht einen Befehl auf einem benannten Host anfordern. Ein allgemeiner Befehl zusammen mit einem weitreichend vertrauenswürdigen privaten Schlüssel verleiht jedoch deutlich mehr Macht, als die meisten Aufgaben brauchen. Begrenze Hostidentität, Konto, Befehlsform und Ausgabe entsprechend dem Zweck der Aktion.

Sallyport verwendet dieses Ausführungsmodell für HTTP-Aufrufe und SSH-Befehle: Zugangsdaten bleiben im verschlüsselten Tresor, und der Agent erhält das Aktionsergebnis statt des Geheimnisses. Das hilft aber nur, wenn du weiterhin enge Aktionen anbietest und Freigaben wählst, die zu ihrer Wirkung passen.

## Die Aktionsbeschreibung muss sagen, was das Schema nicht ausdrücken kann

OpenAPI-Beschreibungen sind wichtig, weil Agenten sie als Anweisungen lesen. Der Text sollte jedoch Grenzen erklären, statt einen zweiten, widersprüchlichen API-Vertrag einzuschleusen. Erzwinge überprüfbare Grenzen in Schemata und Executoren. Beschreibungen erklären Absicht, Wirkung und Bedingungen, die ein Typsystem nicht ausdrücken kann.

Benenne Operationen nach dem vom Nutzer gewünschten Ergebnis. `getBuildStatus` sagt mehr als `getBuildById`; `createPreviewDeployment` sagt mehr als `postDeployment`. Der Name darf nicht zu viel versprechen. Wenn der Server Arbeit in eine Warteschlange stellt, solltest du die Operation nicht `deployBuild` nennen, außer ihr Ergebnis unterscheidet Annahme und Abschluss.

Schreibe Beschreibungen mit den Details, die ein Agent sonst erraten müsste:

```yaml
operationId: createPreviewDeployment
summary: Queue one tested build for the preview environment
requestBody:
  required: true
  content:
    application/json:
      schema:
        $ref: '#/components/schemas/DeployPreviewRequest'
responses:
  '202':
    description: Request accepted. Deployment work may still be pending.
  '409':
    description: The build already has a preview deployment or cannot enter preview.
```

Für Operationen mit höherer Wirkung reicht eine Zusammenfassung nicht. Halte Ziel, Wirkungsklasse, Freigabeanforderung, Wiederholungsregel und Ergebniszustände in Aktionsmetadaten fest, die neben dem OpenAPI-Dokument liegen. Du kannst `x-`-Erweiterungen verwenden, wenn deine Werkzeuge sie unterstützen, solltest sie aber klar als private Konventionen kennzeichnen. Standardparser für OpenAPI ignorieren unbekannte Erweiterungen. Deshalb muss der Executor sie erzwingen und darf sie nicht nur anzeigen.

Verlasse dich nicht auf eine Beschreibung mit dem Hinweis «mit Vorsicht verwenden». Vorsicht ist ein menschliches Gefühl, keine ausführbare Regel. Ersetze sie durch eine Grenze: ein Projekt, nur Preview, keine beliebigen Umgebungsvariablen, Freigabe bei jeder Ausführung und keine automatische Wiederholung nach einem unbekannten Ergebnis.

Beschreibungen sollten dem Agenten auch sagen, wann er die Aktion ablehnen muss. Eine Hochstufungsaktion kann einen abgeschlossenen Testlauf voraussetzen. Ein Datenexport kann ein vom Kunden geliefertes Aktenzeichen benötigen. Eine Löschung kann eine vorherige Abfrage verlangen, die bestätigt, dass es sich um einen Entwurf handelt. Solche Voraussetzungen reduzieren unnötige Freigaben und machen Audit-Einträge leichter verständlich.

## Teste die Aktion mit einem unachtsamen, aber fähigen Bediener

Ein Test des Erfolgswegs beweist nur, dass die API funktioniert, wenn alle Annahmen stimmen. Teste eine Aktion so, als hätte ein schneller, fähiger Bediener unvollständigen Kontext, veraltete IDs und die Neigung, eine Anfrage nach einem Fehler zu wiederholen. Das entspricht dem Fehlverhalten autonomer Agenten ausreichend, um nützlich zu sein.

Baue eine kleine Testumgebung mit entbehrlichen Objekten und einem Konto auf, dessen Berechtigungen zum vorgesehenen Executor passen. Führe die Aktion anschließend durch Fälle, die ihre Grenzen prüfen:

- Sende ein unbekanntes Eingabefeld und bestätige, dass der Executor es ablehnt.
- Fordere ein Objekt außerhalb des erlaubten Projekts oder Workspaces an.
- Lehne die Freigabe ab und bestätige, dass kein Upstream-Aufruf erfolgt.
- Erzwinge einen Timeout, nachdem der Server eine verändernde Anfrage erhalten hat.
- Gib eine Antwort mit vertraulichen Debug-Daten zurück und bestätige, dass die Filterung sie entfernt.

Prüfe mehr als den endgültigen Zustand in der API. Sieh dir den Freigabetext für den Menschen, die genaue Anfrage des Executors, das Ergebnis für den Agenten und den Audit-Eintrag an. Eine erfolgreiche Anfrage kann den Aktionsvertrag trotzdem verletzen, wenn der Dialog das Ziel verborgen hat, das Ergebnis zu früh einen Abschluss meldete oder das Log eine abgelehnte Anfrage nicht von einer Zurückweisung durch das Upstream-System unterscheiden kann.

Teste bei Aktionen mit Freigabe bei jeder Ausführung auch die Reihenfolge. Der Executor sollte statische Einschränkungen prüfen und genügend sicheren Kontext ermitteln, um eine verständliche Anfrage anzuzeigen, bevor er um Zustimmung bittet. Er darf die Anfrage nicht zuerst senden und erst danach nach Freigabe fragen. Ebenso sollte er keine lange Kette verborgener Leseaufrufe ausführen, die mehr Daten offenlegt, als die endgültige Aktion benötigt.

Teste widerrufene und abgelaufene Zugangsdaten gezielt. Der Executor sollte den Zugriff standardmäßig verweigern, eine sichere Erklärung zurückgeben und wiederholte Aufrufe mit denselben unbrauchbaren Zugangsdaten vermeiden. Eine Wiederholungsschleife gegen abgelehnte Zugangsdaten kann Logs füllen, Rate-Limits auslösen und ein einfaches Zugriffsproblem schwerer diagnostizierbar machen.

Teste zuletzt die Abbruchfunktion. Wenn ein Nutzer den Agenten stoppt, während ein Upstream-Auftrag läuft, sollte der Datensatz angeben, ob die Anfrage nie gesendet wurde, den Server erreicht hat oder in einem unbekannten Zustand blieb. Der Abbruch des lokalen Agent-Prozesses beendet nicht unbedingt eine entfernte Nebenwirkung.

## Veröffentliche weniger Aktionen und mache jede davon vertretbar

Ein kleiner Aktionskatalog ist besser als ein generischer API-Client, weil jede Aktion einen begründeten Vertrag tragen kann. Operationen hinzuzufügen ist einfach. Wahrheitsgemäße Ergebnissemantik, Objektgrenzen, Freigabedialoge und Fehlerverhalten dauerhaft zu pflegen, ist die eigentliche Arbeit.

Beginne mit einer Operation, die einen begrenzten Statusdatensatz abruft. Gib ihr einen Namen, der das Objekt nennt, beschränke IDs auf den vorgesehenen Umfang und gib nur die Felder zurück, die der Agent braucht. Füge danach eine umkehrbare Aktion hinzu und zwinge dich, ihre Regeln für Wiederholung und Freigabe aufzuschreiben, bevor du sie implementierst.

Befördere eine Operation nicht deshalb zu einer Agent-Aktion, weil ein OpenAPI-Generator sie an einem Nachmittag bereitstellen kann. Tu es erst, wenn du erklären kannst, was nach einem Timeout passiert, was der Mensch freigibt, was der Agent sieht und wie du später nachweisen kannst, welche Anfrage ausgeführt wurde. Wenn eine dieser Antworten auf «Der Agent wird sich wahrscheinlich vernünftig verhalten» hinausläuft, gehört der Endpunkt nicht in den Katalog.
