From 8dfab4ba14f1dd02ccb7d7e17a90a7a669c98957 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 13 Apr 2026 14:59:49 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20Payment=20Compliance=20Pack=20=E2=80=94?= =?UTF-8?q?=20Semgrep=20+=20CodeQL=20+=20State=20Machine=20+=20Schema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ausfuehrbares Pruefpaket fuer Payment-Terminal-Systeme: 1. Semgrep-Regeln (25 Regeln in 5 Dateien): - Logging: Sensitive Daten, Tokens, Debug-Flags - Crypto: MD5/SHA1/DES/ECB, Hardcoded Secrets, Weak Random, TLS - API: Debug-Routes, Exception Leaks, IDOR, Input Validation - Config: Test-Endpoints, CORS, Cookies, Retry - Data: Telemetrie, Cache, Export, Queue, Testdaten 2. CodeQL Query-Specs (5 Briefings): - Sensitive Data → Logs - Sensitive Data → HTTP Response - Tenant Context Loss - Sensitive Data → Telemetry - Cache/Export Leak 3. State-Machine-Tests (10 Testfaelle): - 11 Zustaende, 15 Events, 8 Invarianten - Duplicate Response, Timeout+Late Success, Decline - Invalid Reversal, Cancel, Backend Timeout - Parallel Reversal, Unknown Response, Reconnect - Late Response after Cancel 4. Finding Schema (JSON Schema): - Einheitliches Format fuer alle Engines - control_id, engine, status, confidence, evidence, verdict_text Co-Authored-By: Claude Opus 4.6 (1M context) --- .../payment-compliance-pack/README.md | 65 +++++++++++++ .../codeql/cache-export-leak.md | 20 ++++ .../codeql/sensitive-data-to-logs.md | 32 +++++++ .../codeql/sensitive-data-to-response.md | 19 ++++ .../codeql/sensitive-data-to-telemetry.md | 19 ++++ .../codeql/tenant-context-loss.md | 21 +++++ .../schema/finding.schema.json | 45 +++++++++ .../semgrep/payment_api.yml | 37 ++++++++ .../semgrep/payment_config.yml | 30 ++++++ .../semgrep/payment_crypto.yml | 43 +++++++++ .../semgrep/payment_data.yml | 30 ++++++ .../semgrep/payment_logging.yml | 42 +++++++++ .../statemachine/terminal_invariants.md | 25 +++++ .../statemachine/terminal_states.md | 47 ++++++++++ .../statemachine/terminal_testcases.json | 92 +++++++++++++++++++ 15 files changed, 567 insertions(+) create mode 100644 ai-compliance-sdk/payment-compliance-pack/README.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/codeql/cache-export-leak.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-logs.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-response.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-telemetry.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/codeql/tenant-context-loss.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/schema/finding.schema.json create mode 100644 ai-compliance-sdk/payment-compliance-pack/semgrep/payment_api.yml create mode 100644 ai-compliance-sdk/payment-compliance-pack/semgrep/payment_config.yml create mode 100644 ai-compliance-sdk/payment-compliance-pack/semgrep/payment_crypto.yml create mode 100644 ai-compliance-sdk/payment-compliance-pack/semgrep/payment_data.yml create mode 100644 ai-compliance-sdk/payment-compliance-pack/semgrep/payment_logging.yml create mode 100644 ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_invariants.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_states.md create mode 100644 ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_testcases.json diff --git a/ai-compliance-sdk/payment-compliance-pack/README.md b/ai-compliance-sdk/payment-compliance-pack/README.md new file mode 100644 index 0000000..8012727 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/README.md @@ -0,0 +1,65 @@ +# Payment Compliance Pack + +Ausfuehrbares Pruefpaket fuer Payment-Terminal-Systeme. + +## Inhalt + +### Semgrep-Regeln (25 Regeln) + +| Datei | Regeln | Controls | +|-------|--------|----------| +| `payment_logging.yml` | 5 | LOG-001, LOG-002, LOG-014 | +| `payment_crypto.yml` | 6 | CRYPTO-001, CRYPTO-008, CRYPTO-009, KEYMGMT-001 | +| `payment_api.yml` | 5 | API-004, API-005, API-014, API-017 | +| `payment_config.yml` | 5 | CONFIG-001 bis CONFIG-004 | +| `payment_data.yml` | 5 | DATA-004, DATA-005, DATA-013, TELEMETRY-001 | + +### CodeQL-Specs (5 Queries) + +| Datei | Ziel | Controls | +|-------|------|----------| +| `sensitive-data-to-logs.md` | Datenfluss zu Loggern | LOG-001, LOG-002, DATA-013 | +| `sensitive-data-to-response.md` | Datenfluss in HTTP-Responses | API-009, ERROR-005 | +| `tenant-context-loss.md` | Mandantenkontext-Verlust | TENANT-001, TENANT-002 | +| `sensitive-data-to-telemetry.md` | Datenfluss in Telemetrie | TELEMETRY-001, TELEMETRY-002 | +| `cache-export-leak.md` | Leaks in Cache/Export | DATA-004, DATA-011 | + +### State-Machine-Tests (10 Testfaelle) + +| Datei | Inhalt | +|-------|--------| +| `terminal_states.md` | 11 Zustaende, 15 Events, Transitions | +| `terminal_invariants.md` | 8 Invarianten | +| `terminal_testcases.json` | 10 ausfuehrbare Testfaelle | + +### Finding-Schema + +| Datei | Beschreibung | +|-------|-------------| +| `finding.schema.json` | JSON Schema fuer Pruefergebnisse | + +## Ausfuehrung + +### Semgrep + +```bash +semgrep --config payment-compliance-pack/semgrep/ /path/to/source +``` + +### State-Machine-Tests + +Die Testfaelle in `terminal_testcases.json` definieren: +- Ausgangszustand +- Event-Sequenz +- Erwarteten Endzustand +- Zu pruefende Invarianten +- Gemappte Controls + +Diese koennen gegen einen Terminal-Adapter oder Simulator ausgefuehrt werden. + +## Priorisierte Umsetzung + +1. **Welle 1:** 25 Semgrep-Regeln sofort produktiv +2. **Welle 2:** 5 CodeQL-Queries fuer Datenfluesse +3. **Welle 3:** 10 State-Machine-Tests gegen Terminal-Simulator +4. **Welle 4:** Tender-Mapping (Requirement → Control → Finding → Verdict) diff --git a/ai-compliance-sdk/payment-compliance-pack/codeql/cache-export-leak.md b/ai-compliance-sdk/payment-compliance-pack/codeql/cache-export-leak.md new file mode 100644 index 0000000..52a6408 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/codeql/cache-export-leak.md @@ -0,0 +1,20 @@ +# CodeQL Query: Cache and Export Leak + +## Ziel +Finde Leaks sensibler Daten in Caches, Files, Reports und Exportpfaden. + +## Sources +- Sensitive payment attributes (pan, cvv, track2) +- Full transaction objects with sensitive fields + +## Sinks +- Redis/Memcache writes +- Temp file writes +- CSV/PDF/Excel exports +- Report builders + +## Mapped Controls +- `DATA-004`: Temporaere Speicher ohne sensitive Daten +- `DATA-005`: Sensitive Daten in Telemetrie nicht offengelegt +- `DATA-011`: Batch/Queue ohne unnoetige sensitive Felder +- `REPORT-005`: Berichte beruecksichtigen Zeitzonen konsistent diff --git a/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-logs.md b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-logs.md new file mode 100644 index 0000000..3b12750 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-logs.md @@ -0,0 +1,32 @@ +# CodeQL Query: Sensitive Data to Logs + +## Ziel +Finde Fluesse von sensitiven Zahlungsdaten zu Loggern. + +## Sources +Variablen, Felder, Parameter oder JSON-Felder mit Namen: +- `pan`, `cardNumber`, `card_number` +- `cvv`, `cvc` +- `track2`, `track_2` +- `pin` +- `expiry`, `ablauf` + +## Sinks +- Logger-Aufrufe (`logging.*`, `logger.*`, `console.*`, `log.*`) +- Telemetrie-/Tracing-Emitter (`span.set_attribute`, `tracer.*) +- Audit-Logger (wenn nicht maskiert) + +## Expected Result +| Field | Type | +|-------|------| +| file | string | +| line | int | +| source_name | string | +| sink_call | string | +| path | string[] | + +## Mapped Controls +- `LOG-001`: Keine sensitiven Zahlungsdaten im Log +- `LOG-002`: PAN maskiert in Logs +- `DATA-013`: Sensitive Daten in Telemetrie nicht offengelegt +- `TELEMETRY-001`: Telemetriedaten ohne sensitive Zahlungsdaten diff --git a/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-response.md b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-response.md new file mode 100644 index 0000000..6e8a050 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-response.md @@ -0,0 +1,19 @@ +# CodeQL Query: Sensitive Data to HTTP Response + +## Ziel +Finde Fluesse sensibler Daten in HTTP-/API-Responses oder Exception-Bodies. + +## Sources +- Sensible Payment-Felder: pan, cvv, track2, cardNumber, pin, expiry +- Interne Payment DTOs mit sensitiven Attributen + +## Sinks +- JSON serializer / response builder +- Exception payload / error handler response +- Template rendering output + +## Mapped Controls +- `API-009`: API-Antworten minimieren sensible Daten +- `API-015`: Interne Fehler ohne sensitive Daten an Client +- `ERROR-005`: Ausnahmebehandlung gibt keine sensitiven Rohdaten zurueck +- `REPORT-006`: Reports offenbaren nur rollenerforderliche Daten diff --git a/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-telemetry.md b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-telemetry.md new file mode 100644 index 0000000..15ad098 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/codeql/sensitive-data-to-telemetry.md @@ -0,0 +1,19 @@ +# CodeQL Query: Sensitive Data to Telemetry + +## Ziel +Finde Fluesse sensibler Daten in Metriken, Traces und Telemetrie-Events. + +## Sources +- Payment DTO fields (pan, cvv, track2, cardNumber) +- Token/Session related fields + +## Sinks +- Span attributes / trace tags +- Metric labels +- Telemetry events / exporters + +## Mapped Controls +- `TELEMETRY-001`: Telemetriedaten ohne sensitive Zahlungsdaten +- `TELEMETRY-002`: Tracing maskiert identifizierende Felder +- `TELEMETRY-003`: Metriken ohne hochkartesische sensitive Labels +- `DATA-013`: Sensitive Daten in Telemetrie nicht offengelegt diff --git a/ai-compliance-sdk/payment-compliance-pack/codeql/tenant-context-loss.md b/ai-compliance-sdk/payment-compliance-pack/codeql/tenant-context-loss.md new file mode 100644 index 0000000..b2a049b --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/codeql/tenant-context-loss.md @@ -0,0 +1,21 @@ +# CodeQL Query: Tenant Context Loss + +## Ziel +Finde Datenbank-, Cache- oder Exportpfade ohne durchgehenden Tenant-Kontext. + +## Sources +- Request tenant (header, token, session) +- Device tenant +- User tenant + +## Danger Patterns +- DB Query ohne tenant filter / WHERE clause +- Cache key ohne tenant prefix +- Export job ohne tenant binding +- Report query ohne Mandanteneinschraenkung + +## Mapped Controls +- `TENANT-001`: Mandantenkontext serverseitig validiert +- `TENANT-002`: Datenabfragen mandantenbeschraenkt +- `TENANT-006`: Caching beruecksichtigt Mandantenkontext +- `TENANT-008`: Datenexporte erzwingen Mandantenisolation diff --git a/ai-compliance-sdk/payment-compliance-pack/schema/finding.schema.json b/ai-compliance-sdk/payment-compliance-pack/schema/finding.schema.json new file mode 100644 index 0000000..1778ccd --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/schema/finding.schema.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Payment Compliance Finding", + "type": "object", + "required": ["control_id", "engine", "status", "confidence", "evidence", "verdict_text"], + "properties": { + "control_id": { "type": "string" }, + "engine": { + "type": "string", + "enum": ["semgrep", "codeql", "contract_test", "state_machine_test", "integration_test", "manual"] + }, + "status": { + "type": "string", + "enum": ["passed", "failed", "warning", "not_tested", "needs_manual_review"] + }, + "confidence": { "type": "number", "minimum": 0, "maximum": 1 }, + "severity": { + "type": "string", + "enum": ["low", "medium", "high", "critical"] + }, + "evidence": { + "type": "array", + "items": { + "type": "object", + "properties": { + "file": { "type": "string" }, + "line": { "type": "integer" }, + "snippet_type": { "type": "string" }, + "scenario": { "type": "string" }, + "observed_state": { "type": "string" }, + "expected_state": { "type": "string" }, + "notes": { "type": "string" } + }, + "additionalProperties": true + } + }, + "mapped_requirements": { + "type": "array", + "items": { "type": "string" } + }, + "verdict_text": { "type": "string" }, + "next_action": { "type": "string" } + }, + "additionalProperties": false +} diff --git a/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_api.yml b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_api.yml new file mode 100644 index 0000000..36b3921 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_api.yml @@ -0,0 +1,37 @@ +rules: + - id: payment-debug-route + message: Debug- oder Diagnosepfad im produktiven API-Code pruefen. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(/debug|/internal|/test|/actuator|/swagger|/openapi) + + - id: payment-admin-route-without-auth + message: Administrative Route ohne offensichtlichen Auth-Schutz pruefen. + severity: WARNING + languages: [python] + patterns: + - pattern: | + @app.$METHOD($ROUTE) + def $FUNC(...): + ... + - metavariable-pattern: + metavariable: $ROUTE + pattern-regex: (?i).*(admin|config|terminal|maintenance|device|key).* + + - id: payment-raw-exception-response + message: Roh-Exceptions duerfen nicht direkt an Clients zurueckgegeben werden. + severity: ERROR + languages: [python, javascript, typescript] + pattern-regex: (?i)(return .*str\(e\)|res\.status\(500\)\.send\(e|json\(.*error.*e) + + - id: payment-missing-input-validation + message: Zahlungsrelevanter Endpunkt ohne offensichtliche Validierung pruefen. + severity: INFO + languages: [python, javascript, typescript] + pattern-regex: (?i)(amount|currency|terminalId|transactionId) + + - id: payment-idor-risk + message: Direkter Zugriff ueber terminalId/transactionId ohne Pruefung. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(get.*terminalId|find.*terminalId|get.*transactionId|find.*transactionId) diff --git a/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_config.yml b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_config.yml new file mode 100644 index 0000000..2ae0ebf --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_config.yml @@ -0,0 +1,30 @@ +rules: + - id: payment-prod-config-test-endpoint + message: Test- oder Sandbox-Endpunkt in produktionsnaher Konfiguration erkannt. + severity: ERROR + languages: [yaml, json] + pattern-regex: (?i)(sandbox|test-endpoint|mock-terminal|dummy-acquirer) + + - id: payment-prod-debug-flag + message: Unsicherer Debug-Flag in Konfiguration erkannt. + severity: WARNING + languages: [yaml, json] + pattern-regex: (?i)(debug:\s*true|"debug"\s*:\s*true) + + - id: payment-open-cors + message: Offene CORS-Freigabe pruefen. + severity: WARNING + languages: [yaml, json, javascript, typescript] + pattern-regex: (?i)(Access-Control-Allow-Origin.*\*|origin:\s*["']\*["']) + + - id: payment-insecure-session-cookie + message: Unsicher gesetzte Session-Cookies pruefen. + severity: ERROR + languages: [javascript, typescript, python] + pattern-regex: (?i)(httpOnly\s*:\s*false|secure\s*:\s*false|sameSite\s*:\s*["']none["']) + + - id: payment-unbounded-retry + message: Retry-Konfiguration scheint unbegrenzt oder zu hoch. + severity: WARNING + languages: [yaml, json] + pattern-regex: (?i)(retry.*(9999|infinite|unbounded)) diff --git a/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_crypto.yml b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_crypto.yml new file mode 100644 index 0000000..55da435 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_crypto.yml @@ -0,0 +1,43 @@ +rules: + - id: payment-no-md5-sha1 + message: Unsichere Hash-Algorithmen erkannt. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)\b(md5|sha1)\b + + - id: payment-no-des-3des + message: Veraltete symmetrische Verfahren erkannt. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)\b(des|3des|tripledes)\b + + - id: payment-no-ecb + message: ECB-Modus ist fuer sensible Daten ungeeignet. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)\becb\b + + - id: payment-hardcoded-secret + message: Moeglicherweise hartkodiertes Secret erkannt. + severity: ERROR + languages: [python, javascript, typescript, java, go] + patterns: + - pattern-either: + - pattern: $KEY = "..." + - pattern: const $KEY = "..." + - pattern: final String $KEY = "..." + - metavariable-pattern: + metavariable: $KEY + pattern-regex: (?i).*(secret|apikey|api_key|password|passwd|privatekey|private_key|terminalkey|zvtkey|opiKey).* + + - id: payment-weak-random + message: Nicht-kryptographischer Zufall in Sicherheitskontext erkannt. + severity: ERROR + languages: [python, javascript, typescript, java] + pattern-regex: (?i)(Math\.random|random\.random|new Random\() + + - id: payment-disable-tls-verify + message: TLS-Zertifikatspruefung scheint deaktiviert zu sein. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(verify\s*=\s*False|rejectUnauthorized\s*:\s*false|InsecureSkipVerify\s*:\s*true|trustAll) diff --git a/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_data.yml b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_data.yml new file mode 100644 index 0000000..a02a64b --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_data.yml @@ -0,0 +1,30 @@ +rules: + - id: payment-sensitive-in-telemetry + message: Sensitive Zahlungsdaten in Telemetrie oder Tracing pruefen. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(trace|span|metric|telemetry).*(pan|cvv|track2|cardnumber|pin|expiry) + + - id: payment-sensitive-in-cache + message: Sensitiver Wert in Cache-Key oder Cache-Payload pruefen. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(cache|redis|memcache).*(pan|cvv|track2|cardnumber|pin) + + - id: payment-sensitive-export + message: Export oder Report mit sensitiven Feldern pruefen. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(export|report|csv|xlsx|pdf).*(pan|cvv|track2|cardnumber|pin) + + - id: payment-test-fixture-real-data + message: Testdaten mit moeglichen echten Kartendaten pruefen. + severity: WARNING + languages: [json, yaml, python, javascript, typescript] + pattern-regex: (?i)(4111111111111111|5555555555554444|track2|cvv) + + - id: payment-queue-sensitive-payload + message: Queue-Nachricht mit sensitiven Zahlungsfeldern pruefen. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(publish|send|enqueue).*(pan|cvv|track2|cardnumber|pin) diff --git a/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_logging.yml b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_logging.yml new file mode 100644 index 0000000..098a103 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/semgrep/payment_logging.yml @@ -0,0 +1,42 @@ +rules: + - id: payment-no-sensitive-logging-python + message: Sensitive Zahlungsdaten duerfen nicht geloggt werden. + severity: ERROR + languages: [python] + patterns: + - pattern-either: + - pattern: logging.$METHOD(..., $X, ...) + - pattern: logger.$METHOD(..., $X, ...) + - metavariable-pattern: + metavariable: $X + pattern-regex: (?i).*(pan|cvv|cvc|track2|track_2|cardnumber|card_number|karten|pin|expiry|ablauf).* + + - id: payment-no-sensitive-logging-js + message: Sensitive Zahlungsdaten duerfen nicht geloggt werden. + severity: ERROR + languages: [javascript, typescript] + patterns: + - pattern-either: + - pattern: console.$METHOD(..., $X, ...) + - pattern: logger.$METHOD(..., $X, ...) + - metavariable-pattern: + metavariable: $X + pattern-regex: (?i).*(pan|cvv|cvc|track2|cardnumber|pin|expiry).* + + - id: payment-no-token-logging + message: Tokens oder Session-IDs duerfen nicht geloggt werden. + severity: ERROR + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(log|logger|logging|console)\.(debug|info|warn|error).*?(token|sessionid|session_id|authheader|authorization) + + - id: payment-no-debug-logging-prod-flag + message: Debug-Logging darf in produktiven Pfaden nicht fest aktiviert sein. + severity: WARNING + languages: [python, javascript, typescript, java, go] + pattern-regex: (?i)(DEBUG\s*=\s*true|debug\s*:\s*true|setLevel\(.*DEBUG.*\)) + + - id: payment-audit-log-admin-action + message: Administrative sicherheitsrelevante Aktion ohne Audit-Hinweis pruefen. + severity: INFO + languages: [python, javascript, typescript] + pattern-regex: (?i)(deleteTerminal|rotateKey|updateConfig|disableDevice|enableMaintenance) diff --git a/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_invariants.md b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_invariants.md new file mode 100644 index 0000000..529ea98 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_invariants.md @@ -0,0 +1,25 @@ +# Terminal State Machine Invariants + +## Invariant 1 +APPROVED darf ohne expliziten Reversal-Pfad nicht in WAITING_FOR_TERMINAL zurueckgehen. + +## Invariant 2 +DECLINED darf keinen Buchungserfolg oder Success-Report erzeugen. + +## Invariant 3 +duplicate_response darf keinen zweiten Commit und keine zweite Success-Bestaetigung erzeugen. + +## Invariant 4 +DESYNC muss Audit-Logging und Klaerungsstatus ausloesen. + +## Invariant 5 +REVERSAL_PENDING darf nicht mehrfach parallel ausgeloest werden. + +## Invariant 6 +invalid_command darf nie zu APPROVED fuehren. + +## Invariant 7 +terminal_timeout darf nie stillschweigend als Erfolg interpretiert werden. + +## Invariant 8 +Late responses nach finalem Zustand muessen kontrolliert behandelt werden. diff --git a/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_states.md b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_states.md new file mode 100644 index 0000000..d48a34d --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_states.md @@ -0,0 +1,47 @@ +# Terminal Payment State Machine + +## States +- IDLE +- SESSION_OPEN +- PAYMENT_REQUESTED +- WAITING_FOR_TERMINAL +- APPROVED +- DECLINED +- CANCELLED +- REVERSAL_PENDING +- REVERSED +- ERROR +- DESYNC + +## Events +- open_session +- close_session +- send_payment +- terminal_ack +- terminal_approve +- terminal_decline +- terminal_timeout +- backend_timeout +- reconnect +- cancel_request +- reversal_request +- reversal_success +- reversal_fail +- duplicate_response +- invalid_command + +## Transitions +| From | Event | To | +|------|-------|----| +| IDLE | open_session | SESSION_OPEN | +| SESSION_OPEN | send_payment | PAYMENT_REQUESTED | +| PAYMENT_REQUESTED | terminal_ack | WAITING_FOR_TERMINAL | +| WAITING_FOR_TERMINAL | terminal_approve | APPROVED | +| WAITING_FOR_TERMINAL | terminal_decline | DECLINED | +| WAITING_FOR_TERMINAL | terminal_timeout | DESYNC | +| WAITING_FOR_TERMINAL | cancel_request | CANCELLED | +| APPROVED | reversal_request | REVERSAL_PENDING | +| REVERSAL_PENDING | reversal_success | REVERSED | +| REVERSAL_PENDING | reversal_fail | ERROR | +| * | invalid_command | ERROR | +| * | backend_timeout | DESYNC | diff --git a/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_testcases.json b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_testcases.json new file mode 100644 index 0000000..6778a66 --- /dev/null +++ b/ai-compliance-sdk/payment-compliance-pack/statemachine/terminal_testcases.json @@ -0,0 +1,92 @@ +[ + { + "test_id": "ZVT-SM-001", + "name": "Duplicate approved response", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["terminal_approve", "duplicate_response"], + "expected_final_state": "APPROVED", + "invariants": ["Invariant 3"], + "mapped_controls": ["TRANS-004", "TRANS-009", "ZVT-RESP-005"] + }, + { + "test_id": "ZVT-SM-002", + "name": "Timeout then late success", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["terminal_timeout", "terminal_approve"], + "expected_final_state": "DESYNC", + "invariants": ["Invariant 4", "Invariant 7", "Invariant 8"], + "mapped_controls": ["TRANS-005", "TRANS-007", "TERMSYNC-009", "TERMSYNC-010"] + }, + { + "test_id": "ZVT-SM-003", + "name": "Decline must not produce booking", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["terminal_decline"], + "expected_final_state": "DECLINED", + "invariants": ["Invariant 2"], + "mapped_controls": ["TRANS-011", "TRANS-025", "ZVT-RESP-002"] + }, + { + "test_id": "ZVT-SM-004", + "name": "Invalid reversal before approval", + "initial_state": "PAYMENT_REQUESTED", + "events": ["reversal_request"], + "expected_final_state": "ERROR", + "invariants": ["Invariant 6"], + "mapped_controls": ["ZVT-REV-001", "ZVT-STATE-002", "ZVT-CMD-001"] + }, + { + "test_id": "ZVT-SM-005", + "name": "Cancel during waiting", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["cancel_request"], + "expected_final_state": "CANCELLED", + "invariants": ["Invariant 7"], + "mapped_controls": ["TRANS-006", "ZVT-CMD-001", "ZVT-STATE-003"] + }, + { + "test_id": "ZVT-SM-006", + "name": "Backend timeout after terminal ack", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["terminal_ack", "backend_timeout"], + "expected_final_state": "DESYNC", + "invariants": ["Invariant 4", "Invariant 7"], + "mapped_controls": ["TERMSYNC-010", "TRANS-012", "ZVT-SESSION-003"] + }, + { + "test_id": "ZVT-SM-007", + "name": "Parallel reversal requests", + "initial_state": "APPROVED", + "events": ["reversal_request", "reversal_request"], + "expected_final_state": "REVERSAL_PENDING", + "invariants": ["Invariant 5"], + "mapped_controls": ["ZVT-REV-003", "TRANS-016", "TRANS-019"] + }, + { + "test_id": "ZVT-SM-008", + "name": "Unknown response code", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["terminal_ack", "invalid_command"], + "expected_final_state": "ERROR", + "invariants": ["Invariant 6"], + "mapped_controls": ["ZVT-RESP-003", "ZVT-COM-005", "ZVT-STATE-005"] + }, + { + "test_id": "ZVT-SM-009", + "name": "Reconnect and resume controlled", + "initial_state": "SESSION_OPEN", + "events": ["send_payment", "terminal_timeout", "reconnect"], + "expected_final_state": "WAITING_FOR_TERMINAL", + "invariants": ["Invariant 7"], + "mapped_controls": ["ZVT-SESSION-004", "TRANS-007", "ZVT-RT-004"] + }, + { + "test_id": "ZVT-SM-010", + "name": "Late response after cancel", + "initial_state": "WAITING_FOR_TERMINAL", + "events": ["cancel_request", "terminal_approve"], + "expected_final_state": "DESYNC", + "invariants": ["Invariant 4", "Invariant 8"], + "mapped_controls": ["TERMSYNC-008", "TERMSYNC-009", "TRANS-018"] + } +]