Operator-Genehmigungsschleife
Ein Agent, der mit externen Gegenübern kommuniziert, sollte niemals allein nach eigenem Ermessen senden und den Operator intern informieren. Dieses Skill definiert den Vertrag: Jeder ausgehende Entwurf wird als Verpflichtung abgelegt, ein Operator entscheidet über den genauen Text, und ein Zustellungsjournal beweist, was rausgegangen ist.
Wann verwenden
- Ein Agent verfasst Antworten an Kunden, Lieferanten, Investoren oder Partner in einem gemeinsamen Kanal, per E-Mail oder Chat, und ein Mensch muss vor dem Senden genehmigen.
- Sie benötigen eine Prüfspur, die jede gesendete Nachricht mit dem genauen Entwurfstext, dem genehmigenden Operator und dem Entscheidungszeitpunkt verknüpft.
- Sie haben erlebt, dass eine veraltete Genehmigung einen neu geschriebenen Entwurf freigegeben hat, oder zwei Mitarbeiter dieselbe genehmigte Nachricht zweimal zugestellt haben.
- Entwürfe fragen Gegenüber immer wieder nach Tatsachen, die das Journal bereits enthält.
Funktionsweise
Objekte
| Objekt | Bedeutung |
|---|---|
| Verpflichtung | Eine Sache, die wir einem Gegenüber schulden. Status wechselt entworfen, dann genehmigt oder abgelehnt, dann gesendet. Trägt Richtung, Gegenüber, Kanal und einen updated_at-Zeitstempel. |
| Entwurf | Nebenreihe mit dem genauen Entwurfstext, einem SHA-256 davon, Ursprungskoordinaten (Plattform, Kanal, Thread, Benutzer) und Priorität (P0 bis P3). Einer pro Verpflichtung, wird bei erneuter Einreichung ersetzt. |
| Entscheidung | Genehmigung oder Ablehnung eines Operators, aufgezeichnet mit der Operator-ID, einer Nonce und dem Entwurfszeitstempel, gegen den sie getroffen wurde. |
| Genehmigungs-Snapshot | Unveränderlicher Text, Hash, Zeitstempel und Ziel, aufgezeichnet vom bereits autorisierten Entscheidungsschreiber. Fehlende Snapshots können keine Zustellung gewähren. |
| Anspruch | Dauerhafte Reservierung mit einem zufälligen Token und Zustand; maximal ein aktiver Anspruch pro Verpflichtung. |
| Zustellung | Journalzeile, die einen Sendevorgang oder Hinweis für ein (Verpflichtung, Entscheidung)-Paar belegt. |
Das Referenzschema befindet sich in references/approval-ledger.sql.
Einreichen eines Entwurfs
- Eingaben bereinigen. Steuerzeichen entfernen, Leerzeichen in einzeiligen Feldern zusammenziehen und Längenbegrenzungen durchsetzen (Entwurf, Zusammenfassung, Kontext, Gegenüber). Leere oder überdimensionierte Felder werden abgelehnt, nicht stillschweigend abgeschnitten.
- Basisprüfung ausführen (siehe unten). Sie kann die Einreichung ablehnen.
- Entwurfstext mit SHA-256 hashen. Das Hash-Präfix geht in die Zusammenfassung, damit das Genehmigungspanel zeigt, welchen Text es genehmigt.
- Upsert. Wenn bereits eine offene entworfenene Verpflichtung für dasselbe (Gegenüber, Kanal) existiert, den Entwurf-Seitenwagen ersetzen und das
updated_atder Verpflichtung fortschreiben. Diese Fortschreibung ist die Epochenrotation: Jede Entscheidung, die mit der alten Epoche verknüpft ist, kann den neuen Text nicht mehr freigeben. Andernfalls eine neue Verpflichtung mit Statusentworfeneinfügen. - Die Einreichungsquittung nur an ein konfiguriertes, verifiziertes internes Betriebsziel weiterleiten. Wenn der Ursprung dieses interne Ziel ist, dort quittieren. Niemals still: Interne Berichterstattung, kein automatisches externes Antworten. Entwurfs-Hashes, Genehmigungsstatus, Operator-Identität und Workflow-Metadaten aus für Gegenüber sichtbaren Kanälen heraushalten. Unbekannte oder nicht klassifizierte Ursprünge bleiben still; eine Direktnachricht ist nicht automatisch intern.
Wenn ein verifiziertes internes Ziel nicht verfügbar ist, das Einreichungsergebnis im internen Tool-Ergebnis oder der Operator-Oberfläche behalten. Niemals auf ein externes oder unbekanntes Ziel zurückfallen. Ein Tool-Ergebnis, das Außenstehenden zugänglich ist, ist keine interne Oberfläche.
Das Einreichen eines Entwurfs autorisiert keine externe Antwort. Jede richtliniengemäße klärende Frage oder neutrale Antwort ist eine separate Ausgangsentscheidung, unterliegt den bestehenden Einschränkungen (Erwähnung, Kanal, nur Entwurf, eingefroren und niemals) in der Disziplin des Gegenüber-Kanals. Sie darf keine internen Genehmigungs-Metadaten preisgeben.
Basisprüfung
Vor der Einreichung eines Entwurfs die aktuelle Basislinie für das Gegenüber abfragen (ein zeitliches Journal, Vertragsspeicher oder CRM):
- Unterzeichneter oder zugestellter Vertrag in den Aufzeichnungen: Die Einreichung mit Nachweis und Empfehlung ablehnen. Ein Gegenüber nach Spezifikationen zu fragen, nachdem ein Vertrag unterzeichnet wurde, ist genau der Fehler, den diese Prüfung verhindern soll.
- Operator-Überschreibung:
force_despite_signed_contractlässt die Einreichung durch und fügt[BASELINE_OVERRIDE_SIGNED_CONTRACT]in den Entwurfskontext ein. - Prüfdienst nicht erreichbar: Die Einreichung wird fortgesetzt und der Kontext mit
[BASELINE_CHECK_UNAVAILABLE]gestempelt. Das Panel sieht, dass die Sicherung ausgeschaltet war. Fehler deaktivieren die Prüfung niemals stillschweigend. - Wenn Fakten verfügbar sind, die aktuellsten als
[BASELINE FACTS: ...]-Digest an den Kontext anhängen, damit der Entwurf mit aktueller Wahrheit ankommt.
Entscheiden
Das Genehmigungspanel listet Verpflichtungen mit Status entworfen und Richtung wir_schulden_ihnen auf. Genehmigen oder Ablehnen schreibt eine Entscheidungszeile, die die Entwurfsepoche (draft_updated_ts) trägt, und wechselt den Verpflichtungsstatus in derselben Transaktion. Eine Entscheidung, deren Epoche nicht mit dem aktuellen updated_at übereinstimmt, ist veraltet und darf nichts freigeben.
Für eine bereits autorisierte Genehmigungsentscheidung fügt dieselbe Transaktion eine unveränderliche obligation_approval_snapshots-Zeile ein: Entscheidungs- und Verpflichtungs-IDs, aktuelle Entwurfsepoche, genauer Text und SHA-256, Plattform/Kanal/Thread und Art draft_sent. Der Entscheidungsschreiber muss vor dem Schreiben die Autorisierung herstellen; die Referenz authentifiziert niemals einen Operator oder erzeugt eine Entscheidung. Automatische Genehmigungsrichtlinien werden von der Referenz weder aktiviert noch erweitert. Legacy-Entscheidungen ohne Snapshots erfordern explizite Abstimmung oder eine neue Genehmigung; niemals die Erlaubnis aus dem aktuellen veränderlichen Entwurf zurückdatieren.
Zustellen
Die SQLite-Referenz ist references/approval_claims.py. Sie gewährt Sendeerlaubnis, ruft aber niemals den Transport auf. Eine vorhandene lokale Referenzdatenbank verwenden, die aus dem SQL-Fixture initialisiert wurde; das Modul wendet keine Schema- oder Produktionsmigrationen an. Nur ein vertrauenswürdiger Entscheidungsschreiber darf Genehmigungsdatensätze füllen. Alle Schreiber müssen Fremdschlüssel und rekursive Trigger aktivieren und die Schema-Sicherungen einhalten; administrative Datenbankmanipulation liegt außerhalb dieses Modells.
- Gebundene genehmigte Entwürfe ermitteln. Ermittlung ist keine Erlaubnis.
claim()öffnet eine eigeneBEGIN IMMEDIATE-Transaktion, validiert die aktuelle genehmigte Epoche, den genauen Text, den berechneten SHA-256 und das vollständige Ziel gegen den Snapshot und fügt einen eindeutigen Anspruch ein, bevor es seinen Token zurückgibt. Ein Konflikt stoppt den Arbeiter vor dem Transport. Abgeschlossene Quittungen können nicht erneut beansprucht werden. begin_dispatch()validiert die Bindung erneut und ändert atomarclaimedindispatchingmit dem Token. Nur der gewinnende Aufrufer erhält nach dem Commit den genauendraft_textund das Ziel. Niemals Text neu generieren, einen veränderlichen Seitenwagen für den Transport erneut lesen oder die Nutzlast für einen weiteren Versuch wiederverwenden. Ein verschachtelter Aufrufer-Transaktion wird abgelehnt; die Erlaubnis darf nicht von einem späteren Commit des Aufrufers abhängen. Keine Datenbanktransaktion bleibt über den Transport hinweg offen.- Ein bestätigtes erfolgreiches Ergebnis geht an
complete(), das atomar die Zustellungskoordinate aufzeichnet, den Anspruch als zugestellt markiert und die Verpflichtung aufgesendetsetzt. Identische Vervollständigung ist ein No-Op; widersprüchliche Koordinaten schlagen fehl. Der UNIQUE-Schlüssel der Quittung dedupliziert Datensätze, nicht vorherige externe Effekte. - Ausnahmen, Zeitüberschreitungen, Arbeitertod nach begin-dispatch oder fehlgeschlagene Quittungspersistenz hinterlassen einen blockierten Versuch.
mark_unknown()zeichnet Unsicherheit auf. Unbekannte Ansprüche verfallen nie, werden nie erneut geöffnet, automatisch wiederholt oder erlauben einer anderen Entscheidung für diese Verpflichtung, sie zu umgehen. Ein vertrauenswürdiger Aufrufer kannreconcile()mit bestätigter erfolgreicher Koordinate und Nachweis verwenden; das Modul überprüft diesen Nachweis nicht. Eine fehlende Quittung ist kein Beweis für Nichtzustellung.
Die Garantie ist ein automatischer Zustellungsversuch pro genehmigter Entscheidung, nicht genau-einmalige externe Zustellung. Ein Absturz nach begin-dispatch, aber vor dem Transport, kann null Sendungen und einen gehaltenen Anspruch hinterlassen. Das Freigeben eines unbekannten Ergebnisses für einen neuen Versuch würde das Abschirmen des ursprünglichen Ausführers und die Überprüfung der Anbieter-Semantik erfordern; diese Referenz stellt bewusst keine solche Wiederholungsoperation bereit.
| Anspruchszustand | Erlaubte nächste Zustände |
|---|---|
| claimed | dispatching oder vor Dispatch abgebrochen |
| dispatching | delivered oder unknown |
| unknown | delivered nur durch vertrauenswürdige Abgleichung |
| delivered, cancelled | Terminal; Entscheidungsschlüssel kann nicht wiederverwendet werden |
Während ein Anspruch aktiv ist, frieren Datenbanksicherungen Schreibvorgänge auf Verpflichtung, Entwurf und Entscheidung ein, einschließlich Ersetzungen. Snapshots und Ansprüche können nicht gelöscht werden. Abbrechen einer beanspruchten Operation mit ihrem Token vor erneuter Einreichung; das veraltete Token gewährt dann nichts. Nach Beginn des Dispatches neue Bearbeitungen oder Widerruf für die Abstimmung zurückhalten. Dies serialisiert Änderungen, anstatt vorzugeben, eine laufende Operation zurückzurufen.
Abgelehnte Entscheidungen und Legacy-Zeilen ohne Entwurfs-Seitenwagen/Snapshots gelangen nie in diesen externen Entwurfs-Sendepfad. Melden Sie sie in der internen Operator-Oberfläche zur manuellen Bearbeitung. Interne Quittungsfußzeilen bleiben intern:
genehmigt von <operator> · Quittung <decision_id> · Entwurf sha256 <prefix>.
Niemals bereits genehmigten externen Text ändern, um Workflow-Metadaten anzuhängen.
Fokussierte lokale Validierung verwendet temporäre Datenbanken, separate Verbindungen und einen simulierten Versuchszähler, keinen Anbieter oder eine echte Nachricht:
python3 -m unittest discover -s tests/skills -p 'test_approval_delivery_claims.py'.
Die Tests erfordern Python 3.11+ mit SQLite-Serialisierungsunterstützung; die Referenz verwendet nur die Standardbibliothek. Die bestehenden Desk-Pattern-Vertragsprüfungen bleiben eine separate Kompatibilitätsprüfung.
Zeitbegrenzte automatische Genehmigung (optional)
Ein Entwurf kann auto_send_after (Epochensekunden) tragen. Ein Durchlauf genehmigt Entwürfe, deren Frist ohne Entscheidung abgelaufen ist, und zeichnet Operator auto-ttl auf. Die Zustellung erfolgt dann über den normalen Pfad. Operatoraktionen gewinnen immer: Eine Entscheidung wechselt den Status, bevor der Durchlauf ihn sieht, und eine erneute Einreichung rotiert die Epoche und verschiebt oder löscht die Frist. Der Durchlauf überprüft Status und Epoche innerhalb der Schreibe-Transaktion, sodass ein Wettlauf als No-Op aufgelöst wird. Entwürfe ohne Frist bleiben für immer hart gesperrt.
Signalverknüpfung
Ein Entwurf kann die eingehende Verpflichtung benennen, die er beantwortet (signal_obligation_id). Dies ist der einzige wahrheitsgemäße Link für die Latenzmessung (eingehendes Signal zu entworfeuer Antwort) und ermöglicht dem SLA-Scan, diesen eingehenden Eintrag als beantwortet zu behandeln. Die Einreichung ablehnen, wenn die referenzierte Zeile nicht existiert.
Beispiele
Entwurf einreichen
file_request(
draft="Vielen Dank, wir können den Slot bis Freitag halten. Welches Startdatum passt?",
counterparty="acme-lieferant",
context="Antwort auf Lieferfensterfrage",
origin_platform="slack", origin_channel="#acme-geteilt",
origin_thread="1712345678.000100", priority="P1",
signal_obligation_id=412)
-> {obligation_id: 431, draft_sha256: "9f2c...", refiled: false}
Das konfigurierte, verifizierte interne Betriebsziel sieht:
Entwurf zur Genehmigung eingereicht (P1, sha 9f2c8a1b). Warte auf Operator.
Der für das Gegenüber sichtbare Ursprungskanal erhält keine Einreichungsmitteilung. Wenn kein verifiziertes internes Ziel verfügbar ist, bleibt die Quittung im internen Tool-Ergebnis oder der Operator-Oberfläche, ohne externen Fallback.
Erneute Einreichung nach Lenkung
Der Operator bittet um einen kürzeren Entwurf. Die erneute Einreichung für dasselbe (Gegenüber, Kanal) gibt refiled: true zurück, der Seitenwaggentext und -hash ändern sich, und updated_at rückt vor. Eine Genehmigung, die auf der alten Panel-Zeile geklickt wird, trägt die alte Epoche und wird ignoriert.
Zurückweisung durch Basisprüfung
DeskApprovalError: Basisprüfung hat diesen Entwurf abgelehnt: Das Journal zeigt einen unterzeichneten Vertrag für 'acme-lieferant'. Nachweis: Rahmenvereinbarung ausgeführt am 2026-08-14. Empfehlung: nicht fragen. Erneut einreichen mit
force_despite_signed_contract=true, wenn dies wirklich ein neuer Thread ist.
Zustellungsfußzeile in einem internen Kanal
Bestätigt für Freitag, Startdatum 2026-09-08.
genehmigt von operator-a · Quittung 118 · Entwurf sha256 9f2c8a1b2d3e4f50
Invarianten zum Testen
- Einreichungsquittungen gehen nur an konfigurierte, verifizierte interne Betriebe; der Ursprung erhält eine nur, wenn er dieses verifizierte interne Ziel ist.
- Ein unbekannter Ursprung bleibt still. Ein nicht verfügbares internes Ziel verwendet das interne Tool-Ergebnis oder die Operator-Oberfläche, ohne externen Fallback.
- Zweimalige Einreichung für dasselbe (Gegenüber, Kanal) ergibt eine Verpflichtung, zwei Epochen.
- Eine Entscheidung mit einer veralteten Epoche führt nie zu einer Zustellungszeile.
- Zwei gleichzeitige Anspruchsteller ergeben eine Sendeerlaubnis; Verlierer versuchen niemals den Transport.
- Unbekannte Ergebnisse und fehlgeschlagene Quittungspersistenz aktivieren niemals einen automatischen Wiederholungsversuch.
- Erfolgreicher Abschluss zeichnet die Quittung und den Sendestatus in einer Transaktion auf.
- Eine geänderte Epoche, Text, Hash oder Ziel kann keinen Anspruch erwerben oder beginnen.
- Aktive Ansprüche blockieren erneute Einreichung; nur ein vor dem Dispatch erfolgter Abbruch kann diese Sperre aufheben.
- Nicht verfügbare Prüfung stempelt den Marker; Prüfung bei unterzeichnetem Vertrag verweigert ohne Force.
- Auto-ttl feuert niemals gegen Text, den der Operator seitdem erneut eingereicht hat.