§ DOCUMENTATION
Wirkungsbestätigung
„Das System hat ja gesagt“ heißt nicht „es ist geschehen“. Execlave hält fest, woher jedes Ergebnis bekannt ist, legt spätere Beobachtungen neben den ursprünglichen Eintrag statt darüber, und zeigt genau, wie viel von dem, was Ihre Agenten als erledigt melden, darauf beruht, dass es jemand gesehen hat.
Vier Ergebnisse, nicht zwei
Ein Audit-Trail, der nur Erfolg und Fehler kennt, vermischt Fälle, die bei einer Untersuchung getrennt bleiben müssen. Execlave erfasst sie getrennt:
| Was geschehen ist | Trace-Status |
|---|---|
| Eine Richtlinie hat die Aktion gestoppt | policy_blocked |
| Der Aufruf hat das Ziel nie erreicht, oder das Ziel hat nein gesagt | error / timeout |
| Das Ziel hat ja gesagt, und die Wirkung wurde beobachtet | success |
| Das Ziel hat ja gesagt, und niemand hat die Wirkung beobachtet | effect_unconfirmed |
Den vierten Fall verdeckt ein einfaches Erfolg/Fehler-Modell: ein 202, ein Job in der Queue, eine ausstehende Buchung. Wird er als success erfasst, behauptet der Trail etwas, das niemand weiß.
Angeben, woher Sie es wissen: effectEvidence
Ein Trace kann effectEvidence enthalten. Entscheidend ist basis: Es gibt an, woher der Agent weiß, was er behauptet.
| basis | Bedeutung | Zählt als Bestätigung |
|---|---|---|
read_back | Der Agent hat das Ziel abgefragt und die Wirkung gesehen. | Ja |
callback | Das Ziel hat sich zurückgemeldet und sie berichtet. | Ja |
acknowledgement | Das Ziel hat die Anfrage angenommen. Nicht, dass es sie ausgeführt hat. | Nein |
none | Überhaupt kein Signal. | Nein |
Optionale Felder: acknowledgementId (bis 255 Zeichen, die Quittung des Ziels), effectRef (bis 512, die Ressource, die die Aktion erzeugt hat), confirmedAt (ISO 8601) und detail (bis 2000). Zwei Regeln gelten bei der Annahme immer:
status: "effect_unconfirmed"braucht einebasis.noneist eine gültige Antwort.- Eine basis
read_backodercallbackbraucht eineeffectRefoder eineacknowledgementId: Eine Bestätigung, die nichts benennt, ist kein Beleg.
Aus dem SDK melden und später auflösen
resolveTrace eine Resolution an (oder mit POST /api/v1/traces/:traceId/resolutions, das mindestens die Developer-Rolle verlangt, per API-Schlüssel oder angemeldetem Benutzer):// JavaScript (@execlave/sdk 1.8.0+)const trace = exe.startTrace({ agentId: 'refund-agent', input });const job = await payments.refund(orderId, amount); // returns 202 + a job id // The provider accepted the refund. Nobody has seen it happen yet.trace.finish({ status: 'effect_unconfirmed', effectEvidence: { basis: 'acknowledgement', acknowledgementId: job.id },}); // Later, when the webhook arrives or a poller sees the refund:await exe.resolveTrace(trace.traceId, { resolvedStatus: 'success', basis: 'callback', acknowledgementId: job.id, effectRef: 'refund_8Hc2', observedAt: event.created_at,}); # Python (execlave-sdk 1.9.0+)trace.finish( status="effect_unconfirmed", effect_evidence={"basis": "acknowledgement", "acknowledgement_id": job.id},)exe.resolve_trace( trace.trace_id, resolved_status="success", basis="callback", acknowledgement_id=job.id, effect_ref="refund_8Hc2",)Eine Resolution enthält resolvedStatus (success, error oder timeout), eine basis (read_back, callback, manual oder reconciliation) und zwei Zeitpunkte: observedAt, wann die Wirkung eintrat, und wann Execlave sie erfasst hat. Jede Resolution schreibt einen Eintrag ins Audit-Log.
Der Trace wird nie geändert. Resolutions werden nur angefügt. Die Trace-Ansicht zeigt den erfassten Status unverändert, den Verlauf der Resolutions und ein als abgeleitet gekennzeichnetes currentOutcome: Es gilt die Resolution mit dem spätesten observedAt. Widersprechen sich zwei Resolutions, wird das Ergebnis als contradicted markiert, statt dass eine still gewinnt.
Ergebnisstrenge: off, monitor, strict
Jeder Agent hat eine Ergebnisstrenge (outcome strictness). Sie bestimmt, was die Annahme mit einem success ohne bestätigenden Beleg macht (keine effectEvidence, oder eine andere basis als read_back oder callback). Sie folgt derselben Stufung wie die Durchsetzungsmodi Ihrer Richtlinien.
| Modus | Ein success ohne bestätigenden Beleg |
|---|---|
off | Wird angenommen. |
monitor | Wird angenommen und auf der Agentenseite als „strict würde N ablehnen“ angezeigt. Standard für neue Agenten. |
strict | Wird bei der Annahme mit OUTCOME_EVIDENCE_REQUIRED abgelehnt; die Meldung nennt effect_unconfirmed als ehrlichen Status. |
- Neue Agenten starten mit dem Standard Ihrer Organisation, also
monitor, sofern ein Admin ihn nicht geändert hat. Agenten, die es vor dieser Einstellung gab, verhalten sich wieoffund wechseln bei ihrer nächsten Aktualisierung zumonitor. Ein ausdrücklich gesetztesoffbleibt. - Erhöhen braucht Bearbeitungsrechte für den Agenten, Senken die Admin-Rolle. Die Registrierung eines Agenten kann seine Strenge nicht selbst wählen.
- off und monitor messen dasselbe. Die Abdeckung zählt die Erfolge jedes Agenten unabhängig von seiner Strenge. Ein Agent auf off kann also keine Befunde aus einem signierten Bericht entfernen.
Einstellen auf der Agentenseite (Tab Einstellungen) oder mit PATCH /api/v1/agents/:id und outcomeStrictness. Unter strict antwortet ein Batch, aus dem nichts gespeichert wurde, mit 400. In einem Batch, aus dem andere Traces gespeichert wurden, stehen die abgelehnten mit demselben Code in errors:
HTTP/1.1 400 Bad Request{ "error": { "code": "OUTCOME_EVIDENCE_REQUIRED", "message": "This agent requires confirmed outcomes (outcomeStrictness \"strict\"): status \"success\" needs effectEvidence with basis \"read_back\" or \"callback\". If the effect is not confirmed, report status \"effect_unconfirmed\"." }, "accepted": 0, "failed": 1, "errors": [{ "traceId": "tr_9f2c", "code": "OUTCOME_EVIDENCE_REQUIRED", "error": "…" }]}Ab SDK 1.9.0 erreicht ein abgelehnter Trace Ihren Code, statt zu verschwinden. flush() gibt zurück, was gesendet, abgelehnt und nicht zugestellt wurde. Ohne Handler schreibt das JavaScript-SDK auf console.error, das Python-SDK protokolliert auf ERROR. Ein abgelehnter Trace wird nie erneut gesendet, und das SDK meldet ihn nie ersatzweise als success.
// JavaScript (1.9.0+): a refused trace is never resent, so handle itconst exe = new Execlave({ apiKey: process.env.EXECLAVE_API_KEY!, onTraceRejected: (rejections) => { for (const r of rejections) alert(r.traceId, r.code, r.message); },});const { sent, rejected, undelivered } = await exe.flush(); # Python (1.9.0+)exe = Execlave(api_key=os.environ["EXECLAVE_API_KEY"], on_trace_rejected=alert)Das Bestätigungsfenster und die Warteschlange
Eine unbestätigte Aktion hat ein Fenster, in dem sie aufgelöst werden soll: standardmäßig 24 Stunden, je Organisation einstellbar (effect_confirmation_window_hours über PATCH /api/v1/organizations/settings/org, Admin) und je Agent von 1 bis 8760 Stunden überschreibbar. Eine Zahlung und ein nächtlicher Batch brauchen verschiedene Fenster. Ein Trace mit basis none hat nichts, worauf er warten könnte, und gilt sofort als überfällig.
Das Alter wird beim Abfragen berechnet und nie in den Trace geschrieben. Ist eine Aktion ohne Resolution über ihr Fenster hinaus, erscheint sie in der Warteschlange unbestätigter Wirkungen (Traces → Unbestätigt), die älteste zuerst, mit ihrem Beleg und dem letzten Read-back-Ergebnis. Stündlich werden überfällige Einträge eskaliert:
- Hat eine Richtlinie im Modus
require_approvaloder mitfailure_mode: fail_closedfür die Aktion einen Verstoß erfasst, wird ein Incident mit hoher Schwere eröffnet; - jede andere überfällige Aktion löst den Webhook
trace.effect_unconfirmed_agedmit Trace-ID, Agent, Alter, Fenster und basis aus.
Read-back-Prüfungen: Execlave fragen lassen
Statt einen eigenen Poller zu schreiben, können Sie einen Endpunkt benennen, den Execlave zu den unbestätigten Aktionen eines Agenten fragt. Eine Read-back-Prüfung ist einer Ihrer Custom Validators: gleiche URL, gleiches Secret, gleiche HMAC-Signatur, gleiches Timeout und gleicher Netzwerkschutz, mit einer Anfrage vom Typ read_back:
POST https://billing.internal.example.com/execlave/read-backX-Execlave-Signature: sha256=… (HMAC-SHA256 of the body, your validator's secret)X-Execlave-Timestamp: 2026-10-04T14:05:00.000ZX-Execlave-Delivery-Id: 5d0c…X-Execlave-Validator-Id: 2b7e… { "type": "read_back", "deliveryId": "5d0c…", "timestamp": "2026-10-04T14:05:00.000Z", "organizationId": "…", "agentId": "…", "agentName": "refund-agent", "traceId": "tr_9f2c", "acknowledgementId": "job_42", "effectRef": null, "tracedAt": "2026-10-04T14:00:12.000Z", "test": false}Prüfen Sie die Signatur wie bei Validator-Aufrufen, suchen Sie die Aktion über acknowledgementId oder effectRef und antworten Sie mit JSON:
{ "status": "success", "effectRef": "refund_8Hc2", "observedAt": "2026-10-04T14:01:30Z" }{ "status": "pending", "detail": "still in the provider's batch" }{ "status": "unknown" }| Antwort, oder was schiefging | Was Execlave erfasst |
|---|---|
success, error, timeout | Eine Resolution mit basis reconciliation und source system, die als Bestätigung zählt. observedAt ist ohne Angabe der Zeitpunkt der Prüfung; liegt es mehr als 5 Minuten in der Zukunft, ist die Antwort ungültig. |
pending, unknown | Nichts über die Aktion. Der Versuch wird gespeichert, in der Warteschlange angezeigt, und die Aktion wird erneut abgefragt. |
| Timeout, Netzwerk- oder HTTP-Fehler, falsche Form, inaktiver Validator | Nichts über die Aktion, unabhängig vom failMode des Validators. Der Versuch und sein Grund werden gespeichert. |
Eine Prüfung, die nicht antworten kann, erfindet nie ein Ergebnis. Das ist das Gegenteil des Validator-Standards, aus demselben Grund: Ein Validator, der nicht antworten kann, darf keine Aktion durchlassen, und ein Read-back, der nicht antworten kann, darf keine Geschichte schreiben.
- Wann. Nur Aktionen, die noch in ihrem Bestätigungsfenster sind und eine
acknowledgementIdodereffectRefhaben. Die erste Prüfung läuft binnen etwa 5 Minuten, danach verdoppelt sich der Abstand ab 5 Minuten, bis höchstens ein Viertel des Fensters. Ist das Fenster abgelaufen, enden die Prüfungen, und der Eintrag gehört einer Person in der Warteschlange. - Wer. Ein Admin registriert oder entfernt die Prüfung; ein Developer mit Bearbeitungsrechten für den Agenten kann eine Testanfrage senden (
"test": true, nichts wird erfasst). Beides auf der Agentenseite im Tab Einstellungen oder über die API:
# Register (ADMIN): one of your organization's custom validatorscurl -X PUT "https://api.execlave.com/api/v1/agents/$AGENT_ID/read-back-check" \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "validatorId": "2b7e…" }' # Test (DEVELOPER with edit access to the agent). Records nothing.curl -X POST "https://api.execlave.com/api/v1/agents/$AGENT_ID/read-back-check/test" \ -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "acknowledgementId": "job_42" }' # Removecurl -X PUT ".../read-back-check" -d '{ "validatorId": null }' …Abdeckung und der signierte Compliance-Bericht
Die Abdeckung wird über Aktionen berechnet, die ausgeführt wurden: Traces mit policy_blocked, limit_exceeded oder flagged_for_review hatten keine Wirkung zu bestätigen und zählen nicht mit.
| Kennzahl | Bedeutung |
|---|---|
coveragePct | Anteil der Aktionen mit eindeutigem Eintrag: jeder Status außer effect_unconfirmed, oder eine unbestätigte Aktion, die später per read_back, callback oder Ihre Read-back-Prüfung aufgelöst wurde. |
unevidencedSuccess | Davon die Erfolge ohne beobachtete Wirkung: das, was strict ablehnen würde. |
evidencedPct | Anteil der Aktionen, die bestätigt UND belegt sind. Die Zahl, die gegen 100 gehen sollte. |
backlog | Unbestätigte Aktionen ganz ohne Resolution. |
medianMinutesToConfirmation | Und p95MinutesToConfirmation: Zeit vom Trace bis zur ersten bestätigenden Resolution. In GET /api/v1/agents/:id/confirmation-coverage; nicht im signierten Bericht. |
Eine manual-Resolution oder eine von einem Agenten oder einer Person gemeldete reconciliation schließt einen Eintrag, zählt aber nicht als Bestätigung: Niemand hat die Wirkung beobachtet. Jede Kennzahl ist null, nie 0 oder 100, wenn der Zeitraum keine Aktionen enthält.
Compliance-Berichte enthalten dieselben Kennzahlen in confirmationCoverage, im signierten Teil, für den Zeitraum und die Agentenauswahl des Berichts. Ein Bericht, der nur Erfolge und Blockierungen zeigt, ließe den Leser annehmen, alles andere sei angekommen.
"confirmationCoverage": { "coveragePct": 91.4, "confirmed": 1828, "unevidencedSuccess": 212, "evidencedPct": 80.8, "unconfirmed": 172, "total": 2000, "backlog": 38, "scope": "organization", "windowFrom": "2026-09-01T00:00:00.000Z", "windowTo": "2026-09-30T23:59:59.999Z"}Was das nicht abdeckt
- Belege werden bezeugt, nicht nachgeprüft. Eine basis
read_back, eine Callback-Resolution oder eine Read-back-Antwort ist die Aussage Ihres Systems, authentifiziert durch Ihren API-Schlüssel oder die Signatur Ihres Validators. Execlave kontaktiert das nachgelagerte System nicht selbst. - Ein Agent, der success ohne Beleg meldet, wird in
unevidencedSuccessgezählt, nicht als falsch erkannt. Erst strict stoppt das. - Read-back-Prüfungen brauchen eine Kennung. Ein unbestätigter Trace ohne
acknowledgementIdund ohneeffectRefwird nie abgefragt. - Ältere SDKs. Wirkungsbelege brauchen @execlave/sdk 1.8.0 oder execlave-sdk 1.9.0; der Umgang mit abgelehnten Traces braucht in beiden 1.9.0.