- job_schema: geschlossene Job-Type-Allowlist (C5_SAVE_OBJECT/C5_DELETE_OBJECT), Pfad-/Längen-Validierung - job_state_machine: deterministische States (CREATED/READY/CLAIMED/EXECUTING/SUCCEEDED/FAILED) - job_claim: atomare Claim-/Lease-/Recovery-Logik (kein TOCTOU) - job_store: getrennte SQLite-Inbox-DBs (c5a_save.db/c5a_delete.db), delegiert an job_claim - save_executor_core: SAVE-only, Content-Rekonstruktion, Provenance-Validierung - delete_executor_core: DELETE-only, AUTH.3D-Composition, TOCTOU-Defense (Re-Read nach Claim) - test_job_channel: T1-T40 + adversarial (72 Tests) - test_job_channel_adversarial: adversarial + Substitution + DB-Manipulation - sensitivity_proof_auth3e: Mutationen A-L (12/12 Invarianten PRESENT) - AUTH3B/3C/3D/3E_DESIGN: autoritative Security-Dokumentation (e25 Reconciliation) COMMAND != AUTHORIZATION. Kein generischer Dispatcher. RQ credential-free. Keine produktive Mutation. Keine echten Credentials.
20 KiB
AUTH.3D — HUMAN DELETE APPROVAL AUTHENTICITY
Status: SECURITY DESIGN + CODE + ISOLATED TESTS + REVIEW ONLY (KEIN produktives Deployment)
Datum: 2026-08-27
Mission Type: SECURITY DESIGN + CODE + ISOLATED TESTS + REVIEW ONLY
Baseline: AUTH.1 (40bbc40) + AUTH.2 (edcb4902) + AUTH.3A (a11c1bb) + AUTH.3B + AUTH.3C = COMPLETE
⚠️ Dies ist ein Design + Code + Test-Dokument. Es wird KEIN produktives Deployment ausgeführt, kein echter Signing Key erzeugt, kein Christians Private Key erzeugt, kein echter Public Key deployed, keine ENV geändert, kein Container erstellt, kein Executor deployed, keine produktive SAVE/DELETE-Probe. Bei Zweifel: FAIL CLOSED + HARD STOP.
1. CURRENT APPROVAL FLOW (Phase 1) — rekonstruiert (READ-ONLY)
1a. Vollständiger Flow
Delete Request → State Machine → Approval Creation → Approval Persistence
→ DeleteExecutor → Approval Validation → Tolaria DELETE → Ledger/Consumption
- Delete Request: Ein Forgejo-Commit enthält einen DELETE-ObjectChange (
operation == OP_DELETE_REQUEST). - State Machine: Commit wird in C5-State-Machine verarbeitet (C5AStore, c5a.db).
- Approval Creation:
cmd_c5_delete_approve(CLI, rq_c5_cli.py Z.355) →store.create_delete_approval(). - Approval Persistence: SQLite-Tabelle
delete_approvals(c5a.db). - DeleteExecutor:
cmd_c5_delete_execute(CLI, Z.424) →DeleteExecutor.execute(). - Approval Validation:
_validate_approval()(rq_c5_delete.py Z.105) — Invarianten D/E/F/I. - Tolaria DELETE:
_do_delete()→client.delete(). - Ledger/Consumption:
mark_delete_approval_used()→approval_status='USED', Commit → ST_UPDATING_SEARCH.
1b. Wer kann Approval heute erzeugen?
- NUR der CLI-Befehl
approve-delete(cmd_c5_delete_approve). Kein Code erzeugt Approval automatisch (Invariante B/C). - Jeder, der die CLI im RQ-Container ausführen kann (User
hermes), kann eine Approval erzeugen. approved_byist ein frei wählbares CLI-Argument (Defaulthuman:christian). KEINE kryptographische Bindung an Christian.
1c. Exakte Felder (DB-Tabelle delete_approvals)
| Feld | Typ | Bedeutung |
|---|---|---|
approval_id |
TEXT (uuid4) | Eindeutige ID |
workflow_commit |
TEXT | Commit-Binding |
object_change_id |
INT | ObjectChange-Binding |
object_id |
TEXT | Objekt-Binding |
path |
TEXT | Pfad-Binding |
operation |
TEXT | 'DELETE' |
approval_status |
TEXT | APPROVED/USED/REVOKED |
approved_by |
TEXT | frei wählbar (Default human:christian) |
approval_nonce |
TEXT (uuid4) | Nonce (kryptographisch zufällig, aber NICHT signiert) |
approved_at |
INT (ms) | Zeitpunkt |
used_at |
INT (ms) | Single-Use-Zeitpunkt |
1d. Bestehende Bindings (im Code verifiziert)
- Object-Binding:
_validate_approvalZ.143 —approval.object_id == oid(Invariante E). - Commit-Binding: Z.136 —
approval.workflow_commit == commit_sha(Invariante F). - Path-Binding: Z.150 —
approval.path == path(Invariante I). - Operation-Binding:
create_delete_approvalsetztoperation='DELETE'fest. - Nonce:
approval_nonce= uuid4, aber nicht signiert, nicht verifiziert. - Single-Use:
mark_delete_approval_used→approval_status='USED';_validate_approvalprüftapproval_status == 'APPROVED'. - Mission-Binding: FEHLT — kein
mission_id-Feld. - Provenance-Binding: FEHLT — kein
expected_provenance_hash-Feld. - Expiry: FEHLT — kein
expires_at-Feld. - Actor-/Identity-Information:
approved_by(frei wählbar). - Authentizitätsprüfung: KEINE — es gibt keine kryptographische Prüfung, dass die Approval von Christian stammt.
1e. Kernbefund
HUMAN_APPROVAL_AUTHENTICITY_GAP = OPEN. Die Approval ist eine reine DB-Zeile mit
frei wählbarem approved_by. Jeder mit CLI-/DB-Zugriff (RQ/Hermes, User hermes)
kann eine syntaktisch perfekte Approval erzeugen. Es gibt keine kryptographische
Bindung an Christian. → DELETE_OPERATION_ACTIVATION bleibt BLOCKED.
2. THREAT MODEL (Phase 2)
⚠️ NUR ANALYSE. FAIL CLOSED.
| Threat | CURRENT_PROTECTION | CURRENT_GAP | TARGET_CONTROL | FAIL_CLOSED_BEHAVIOR |
|---|---|---|---|---|
| T1 RQ erzeugt selbst Approval | CLI-Zugriff (User hermes) | RQ kann approve-delete ausführen |
RQ besitzt keinen Signing Key → kann keine gültige signierte Approval erzeugen | DELETE_DENIED |
| T2 Hermes erzeugt selbst Approval | Gleiche Boundary wie RQ | Hermes kann CLI ausführen | Hermes besitzt keinen Signing Key | DELETE_DENIED |
| T3 Rain erzeugt Approval | Separater Container | Rain hat keinen CLI-Zugriff auf c5a.db | Rain besitzt keinen Signing Key | DELETE_DENIED |
| T4 SAVE Executor erzeugt Approval | Separater Container (AUTH.3C) | Kein CLI-Zugriff auf c5a.db | SAVE Executor besitzt keinen Signing Key | DELETE_DENIED |
| T5 DELETE Executor erzeugt Approval | Separater Container (AUTH.3C) | Kein CLI-Zugriff auf c5a.db | DELETE Executor ist verify-only, besitzt keinen Signing Key | DELETE_DENIED |
| T6 Agent verändert gespeicherte Approval | DB-Zugriff | DB-Zeile kann geändert werden | Signatur über Payload → Änderung invalidiert Signatur | DELETE_DENIED |
| T7 Agent verändert Object nach Approval | Object-Binding (E) | Nur DB-Vergleich, nicht kryptographisch | Object im signierten Payload → Änderung invalidiert Signatur | DELETE_DENIED |
| T8 Agent verändert Commit nach Approval | Commit-Binding (F) | Nur DB-Vergleich | Commit im signierten Payload | DELETE_DENIED |
| T9 Agent verändert Path nach Approval | Path-Binding (I) | Nur DB-Vergleich | Path im signierten Payload | DELETE_DENIED |
| T10 Approval wird kopiert | approval_id uuid4 | Kopie ist gültig (keine Signatur) | Signatur + Single-Use → Kopie hat gleiche Signatur, aber Nonce/consumed | DELETE_DENIED (Replay) |
| T11 Approval wird wiederverwendet | Single-Use (USED) | Nur DB-Status | Signatur + consumed-check | DELETE_DENIED |
| T12 Approval wird zwischen Missions übertragen | Kein mission_id | Kein Mission-Binding | mission_id im signierten Payload | DELETE_DENIED |
| T13 alte Approval nach State Change | Commit-Status-Check (Gate 2) | Nur DB-Status | State-Check + Signatur | DELETE_DENIED |
| T14 Nonce wird wiederverwendet | uuid4 | Nonce nicht signiert/verifiziert | Nonce im signierten Payload + consumed-check | DELETE_DENIED |
| T15 DB-Eintrag wird manipuliert | — | DB-Zeile allein erzeugt gültige Approval | Signatur → DB-Forgery ohne Private Key unmöglich | DELETE_DENIED |
| T16 Approval aus Backup wiederhergestellt | — | Backup enthält gültige Approval | Signatur + consumed-check + expires_at | DELETE_DENIED |
| T17 Approval nach Executor-Restart erneut verwendet | Single-Use (USED) | Nur DB-Status | consumed-check + Signatur | DELETE_DENIED |
| T18 Race zwischen Verify und Delete | — | TOCTOU-Fenster | Atomare Reservation (RESERVED) | DELETE_DENIED |
| T19 LLM erzeugt syntaktisch perfekte Fake-Approval | — | Keine Signatur | Signatur → LLM ohne Private Key kann nicht signieren | DELETE_DENIED |
| T20 kompromittierter RQ-Prozess versucht Approval-Bypass | — | RQ kann CLI ausführen | RQ besitzt keinen Signing Key | DELETE_DENIED |
Kern-Gap: Alle Bindings (Object/Commit/Path) sind nur DB-Vergleiche, nicht
kryptographisch. approved_by ist frei wählbar. Es fehlt eine kryptographische
Bindung an Christian.
3. HUMAN IDENTITY ROOT (Phase 3) — Optionen
⚠️ NUR BEWERTUNG. KEINE Keys erzeugen.
| Option | HUMAN_AUTH | LLM_CAN_FORGE | RQ_CAN_FORGE | DELETE_EXEC_CAN_FORGE | PRIVATE_SECRET_EXPOSURE | REPLAY_RES | AUDIT | ROTATION | REVOCATION | BACKUP_RISK | OP_COMPLEXITY | STACK_COMPAT | OFFLINE_RECOVERY |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A: HMAC (geteiltes Secret) | Mittel | Nein (ohne Secret) | Nein (ohne Secret) | Nein (verify-only) | Hoch (Secret muss bei Verifier liegen) | Mittel | Mittel | Ja | Ja | Mittel | Niedrig | Hoch | Ja |
| B: Asymmetrisch (Ed25519) | Hoch | Nein | Nein | Nein (verify-only) | Niedrig (nur Public Key bei Verifier) | Hoch | Hoch | Ja | Ja | Niedrig | Mittel | Hoch (Python stdlib/cryptography) | Ja |
| C: Forgejo-signiertes Artefakt | Mittel | Nein | Nein | Nein | Mittel (Key bei Forgejo) | Mittel | Hoch | Ja | Ja | Mittel | Hoch | Hoch | Mittel |
| D: Separater Approval-Service | Hoch | Nein | Nein | Nein | Niedrig | Hoch | Hoch | Ja | Ja | Niedrig | Hoch (neue Infrastruktur) | Niedrig | Mittel |
| E: Telegram + kryptogr. Bindung | Mittel | Nein | Nein | Nein | Mittel | Mittel | Mittel | Ja | Ja | Mittel | Mittel | Hoch | Ja |
| F: Andere minimal sichere | — | — | — | — | — | — | — | — | — | — | — | — | — |
Bewertung:
- OPTION B (Ed25519 asymmetrisch) ist die stärkste und stack-kompatible Lösung:
Christian besitzt den Private Key, der DELETE Executor kennt nur den Public Key.
LLM/RQ/SAVE/DELETE-Executor können ohne Private Key nicht signieren.
Python
cryptography-Bibliothek (oderpynacl) unterstützt Ed25519 nativ. - OPTION A (HMAC) ist schwächer: das geteilte Secret müsste beim Verifier liegen, was die Exposure-Fläche vergrößert. Nicht bevorzugt.
- OPTION C (Forgejo-signiert) ist möglich, aber komplexer und bindet an Forgejo.
- OPTION D (separater Service) erfordert neue Infrastruktur → Scope-Creep.
- OPTION E (Telegram) allein ist KEIN kryptographischer Proof (siehe §7).
Empfehlung: OPTION B (Ed25519 asymmetrisch).
4. PREFERRED SECURITY PROPERTY (Phase 4)
Bevorzugte Eigenschaft (bestätigt):
- Christian: PRIVATE KEY (Ed25519)
- DELETE Executor: PUBLIC KEY ONLY (verify-only)
- RQ/Hermes: NO PRIVATE KEY
- SAVE Executor: NO PRIVATE KEY
- Rain: NO PRIVATE KEY
- Tolaria: NO PRIVATE KEY
Gegen reale Architektur bewertet:
- Python
cryptography/pynaclist im Stack verfügbar (C5-Caller sind Python). - Keine neue Infrastruktur nötig.
- Der DELETE Executor kann eine Approval verifizieren, aber nicht erzeugen.
- Bestätigt als bevorzugte Lösung.
5. APPROVAL PAYLOAD (Phase 5) — kanonisch
Kanonischer Payload
{
"approval_version": 1,
"approval_id": "<uuid4>",
"mission_id": "<mission-id>",
"delete_request_id": "<delete-request-id>",
"operation": "DELETE",
"object_id": "<object-id>",
"vault_path": "<vault-path>",
"expected_commit": "<commit-sha>",
"expected_provenance_hash": "<sha256>",
"nonce": "<uuid4>",
"issued_at": "<ISO-8601-UTC>",
"expires_at": "<ISO-8601-UTC>"
}
Canonicalization
- CANONICALIZATION: Deterministische Serialisierung: Felder in fester Reihenfolge
(wie oben), keine Duplikate, keine Whitespace-Varianz, UTF-8, keine Unicode-Normalisierung
(exakte Bytes), Pfad-Normalisierung (kein
./, kein.., keine doppelten Slashes). - ENCODING: UTF-8, JSON ohne optionale Felder (nur die 12 Pflichtfelder).
- HASH: SHA-256 über den kanonisierten Payload-Bytes.
- SIGNATURE_INPUT: Die kanonisierten Payload-Bytes selbst (nicht der Hash) werden signiert (Ed25519 signiert intern den Hash). Keine Signatur über frei formatierte Texte.
6. APPROVAL SIGNATURE (Phase 6) — Ed25519
- SIGNATURE_ALGORITHM: Ed25519 (RFC 8032), via Python
cryptographyoderpynacl. - PRIVATE_KEY_OWNER: Christian (einziger Besitzer).
- PRIVATE_KEY_LOCATION: Christians vertrauenswürdiges Gerät (NICHT im Stack).
- PUBLIC_KEY_LOCATION: DELETE Executor-Konfiguration (read-only, injiziert via Secret/File).
- KEY_ID: SHA-256-Hash des Public Keys (kurz, zur Key-Identifikation).
- SIGNATURE_FORMAT: Ed25519-Signatur (64 Bytes), Base64-URL-encoded.
- VERIFICATION:
verify(public_key, canonical_payload_bytes, signature). - ROTATION: Neuer Key → neue KEY_ID; alte Approvals mit altem Key bleiben bis Expiry gültig (Multi-Key-Transition).
- REVOCATION: Key-Revocation-Liste (KEY_ID → revoked); verifier prüft.
- MULTI_KEY_TRANSITION: Verifier akzeptiert mehrere Public Keys (aktuelle + vorherige), markiert ältere als "transitioning".
Private Key darf NICHT liegen in: RQ ENV, Hermes ENV, Rain ENV, SAVE Executor, DELETE Executor, Forgejo Repo, C5 DB, Tolaria, Logs, Reports.
7. APPROVAL CREATION CHANNEL (Phase 7)
⚠️ NUR DESIGN. KEINE Implementierung in AUTH.3D (nur Code + Tests).
Modelle
| Modell | UX | Sicherheit | Stack-Kompatibilität |
|---|---|---|---|
| A: Lokales Signing Tool auf Christians Gerät | Mittel (Christian signiert manuell) | Hoch (Private Key nie im Stack) | Hoch (Python-Skript) |
| B: Separater Approval-Container/Service | Niedrig | Hoch | Niedrig (neue Infrastruktur) |
| C: Telegram Approval → separater Signer | Hoch | Mittel (Signer muss getrennt sein) | Mittel |
| D: Forgejo Workflow | Mittel | Mittel | Hoch |
| E: Anderer sicherer Kanal | — | — | — |
Empfehlung: OPTION A (lokales Signing Tool auf Christians Gerät). Christian erzeugt den kanonischen Payload (aus dem Delete-Request), signiert ihn mit seinem Private Key, und übergibt die signierte Approval (Payload + Signatur + KEY_ID) an den DELETE Executor (via CLI/Inbox). Der Executor verifiziert mit dem Public Key.
WICHTIG (strikte Unterscheidung):
- HUMAN_INTENT: Ein Telegram-Text "Ja"/"Approve"/"Delete" ist NUR Intent, KEIN kryptographischer Proof.
- CRYPTOGRAPHIC_APPROVAL_ARTIFACT: Die signierte Approval (Payload + Signatur) ist der einzige gültige Proof.
- RQ darf NICHT aus einem Telegram-Text den finalen Approval-Datensatz erzeugen können (ohne Christians Private Key).
8. APPROVAL VERIFICATION (Phase 8)
DeleteExecutor MUSS VOR DELETE prüfen (alle, sonst DELETE_DENIED):
- Schema gültig (kanonischer Payload)
- Unterstützte Approval-Version
- Signatur gültig (Ed25519, Public Key)
- Key nicht revoked
- Operation == DELETE
- Mission stimmt
- Delete Request stimmt
- Object stimmt
- Path stimmt
- Commit stimmt
- Provenance stimmt
- Nonce stimmt
- issued_at plausibel (nicht in der Zukunft)
- expires_at nicht überschritten
- Approval noch nicht consumed
- State erlaubt Delete
- kein Replay
- kein Cross-Object-Reuse
- kein Cross-Mission-Reuse
Jeder Fehler → DELETE_DENIED. KEIN Tolaria HTTP DELETE.
9. TOCTOU / RACE SAFETY (Phase 9)
- VERIFY → STATE CHANGE → DELETE: Zwischen Verification und Mutation gibt es ein Fenster.
- Lösung: Atomare Reservation in der DB: Approval-Status
APPROVED → RESERVED(mitexecution_attempt_id+idempotency_key) in einer SQLite-Transaktion, BEVOR der Tolaria-DELETE ausgeführt wird. Nur eine Reservation pro Approval möglich. - DB Transaction:
UPDATE ... SET approval_status='RESERVED' WHERE approval_status='APPROVED'— atomar, nur wenn noch APPROVED. - Crash before delete: Approval bleibt RESERVED → Recovery: prüfen, ob DELETE tatsächlich ausgeführt wurde (Read-Back). Wenn nicht → zurück zu APPROVED (oder neuer Attempt mit neuem idempotency_key).
- Crash after delete before ledger: Read-Back zeigt Ziel absent → Ledger nachtragen, Approval → CONSUMED.
- Retry: Idempotenz via
idempotency_key— gleicher Attempt wird nicht doppelt ausgeführt. - Uncertain network result: DELETE_OUTCOME_UNKNOWN — der Executor darf bei Unsicherheit NICHT blind wiederholen. Er meldet OUTCOME_UNKNOWN und wartet auf manuelle Klärung (Read-Back).
Recovery State für DELETE_OUTCOME_UNKNOWN: Approval bleibt RESERVED; ein manueller Read-Back entscheidet, ob CONSUMED (Ziel absent) oder zurück zu APPROVED (Ziel noch da).
10. SINGLE USE (Phase 10)
Approval Lifecycle:
CREATED → VERIFIED → RESERVED → EXECUTED → CONSUMED
| Zustand | Verhalten |
|---|---|
| INVALID | DELETE_DENIED (Signatur/Binding-Fehler) |
| EXPIRED | DELETE_DENIED (expires_at überschritten) |
| REVOKED | DELETE_DENIED (Key oder Approval revoked) |
| FAILED | DELETE_DENIED (Execution-Fehler) |
| OUTCOME_UNKNOWN | Kein blinder Retry; manuelle Klärung |
Eine Approval darf nach CONSUMED niemals erneut ausführbar sein. Der consumed-check ist Teil der Verification (§8, Punkt 15) und der Reservation (§9).
11. STORAGE (Phase 11)
Was wird gespeichert:
- Payload (kanonisch)
- Signature (Ed25519, Base64-URL)
- Public Key ID (KEY_ID)
- Verification Result (PASS/DENIED + Reason)
- consumed_at
- execution_attempt (attempt_id, idempotency_key)
- Result (DELETE_OK / DELETE_OUTCOME_UNKNOWN / DELETE_DENIED)
Was wird NICHT gespeichert:
- Private Key
- Signing Secret
DB-Manipulationsrisiko: Eine DB-Zeile allein darf keine gültige Approval erzeugen. Selbst vollständige Schreibkontrolle über die Approval-DB darf ohne Christians Private Key keine neue gültige Approval erzeugen können (Signatur fehlt → DENIED).
12. ISOLATED IMPLEMENTATION (Phase 12)
⚠️ NUR Code + Tests. KEIN produktives Deployment.
Modular (keine Vermischung mit Tolaria HTTP):
approval_payload.py— kanonischer Payload, Canonicalization, Encoding, Hashapproval_signature.py— Ed25519 sign/verify (synthetische Test-Keypairs)approval_verifier.py— Verification-Logik (alle §8-Checks)approval_state.py— Lifecycle (CREATED→VERIFIED→RESERVED→EXECUTED→CONSUMED), Single-Use, Reservation
Bestehende C5-Invarianten erhalten. Keine Änderung an Tolaria-HTTP-Code.
13. TEST CONTRACT (Phase 13)
⚠️ NUR synthetische Test-Keypairs. KEINE echten Keys.
T1–T30 (siehe Freigabe):
- T1 gültige Christian-Approval → PASS
- T2 falsche Signatur → DENIED
- T3 falscher Public Key → DENIED
- T4 Payload nach Signatur verändert → DENIED
- T5 Object verändert → DENIED
- T6 Path verändert → DENIED
- T7 Commit verändert → DENIED
- T8 Provenance verändert → DENIED
- T9 Mission verändert → DENIED
- T10 Request-ID verändert → DENIED
- T11 Nonce verändert → DENIED
- T12 expired → DENIED
- T13 future-issued invalid → DENIED
- T14 falsche Operation → DENIED
- T15 unbekannte Version → DENIED
- T16 malformed payload → DENIED
- T17 malformed signature → DENIED
- T18 Replay → DENIED
- T19 consumed Approval → DENIED
- T20 cross-object reuse → DENIED
- T21 cross-mission reuse → DENIED
- T22 DB fake row ohne Signature → DENIED
- T23 DB fake row mit erfundener Signature → DENIED
- T24 DELETE Executor kann keine Approval erzeugen
- T25 RQ besitzt keinen Signing Key
- T26 SAVE Executor besitzt keinen Signing Key
- T27 Logs enthalten keinen Private Key
- T28 DB enthält keinen Private Key
- T29 Retry nach confirmed delete führt nicht zu zweitem Delete
- T30 OUTCOME_UNKNOWN führt nicht zu blindem Retry
Adversarial: canonicalization ambiguity, duplicate JSON keys, Unicode normalization, path normalization, signature substitution, key-id substitution, oversized payload, malformed timestamps, nonce collision, stale state, concurrent execution.
14. TEST SENSITIVITY (Phase 14)
Mutationen (jede muss Tests ROT machen):
- A Signaturprüfung entfernen
- B Object Binding entfernen
- C Commit Binding entfernen
- D Nonce Binding entfernen
- E Expiry entfernen
- F consumed-check entfernen
- G Operation-check entfernen
- H Mission Binding entfernen
- I Provenance Binding entfernen
- J Replay-Schutz entfernen
15. REGRESSION (Phase 15)
Volle relevante C5-Test-Suite. Keine bestehenden Sicherheitsinvarianten abschwächen. Baseline-Fails separat beweisen. Keine unrelated Reparaturen.
16. SECURITY REVIEW (Phase 16)
- NO_PRIVATE_KEY_IN_REPO / ENV / DB / LOGS
- RQ_CANNOT_SIGN / HERMES_CANNOT_SIGN / RAIN_CANNOT_SIGN / SAVE_EXECUTOR_CANNOT_SIGN / DELETE_EXECUTOR_CANNOT_SIGN
- DELETE_EXECUTOR_VERIFY_ONLY
- SIGNATURE_FAIL_CLOSED / REPLAY_FAIL_CLOSED / EXPIRY_FAIL_CLOSED / STATE_FAIL_CLOSED
17. COMMIT / PUSH (Phase 17)
Nur AUTH.3D-relevante Dateien. Vor Commit: git diff, git status, Secret-Scan, Private-Key-Pattern-Scan. Keine echten Keys. Tests nur mit synthetischen Test-Keypairs. FF-only Push. HEAD == origin/main verifizieren.
18. FRESH CHECKER (Phase 18)
⚠️ Wird als unabhängiger Subagent ausgeführt.
19. FINAL REPORT (Phase 19)
⚠️ Wird nach Fresh Checker ausgefüllt.