# ScamHunter Version 4

Der bestehende Desktop bleibt eine statische Anwendung. Version 4 behält den
localStorage-Schlüssel `scamwatch-desktop-v3` und migriert neue optionale Felder
mit Standardwerten. Keine Spielstände werden beim Update gelöscht.

## Bankübergang

Die Anmeldung darf während einer NPC-Antwort eintreffen. `ensureBankProgress`
plant `bank_ready` idempotent anhand von Szenenstatus, Anmeldung und Verbindung.
Bestehende Antwortjobs laufen vorher fertig. Verwaiste busy-Zustände ohne Jobs
werden dabei repariert. Der Job prüft vor Ausführung seine Voraussetzungen.

## Zwei Geräte

Der PC ist alleiniger Schreiber des Spielstands und führt die Simulation aus.
`companion/host.js` sendet einen begrenzten Telefon-Snapshot an `api/phone.php`.
Der Snapshot enthält Dialog, Status, Sprache und Telefonhinweise; keine Notizen,
Beweisdateien, Browserinhalte, Bankzugangsdaten oder sonstigen Desktop-Inhalte.
Das Handy lädt `phone.html` und `companion/mobile.js`, ohne die Spielengine.

PHP speichert Relay-Sitzungen ausserhalb des Webroots im System-Temp-Verzeichnis
(Dateirechte 0600, Verzeichnis 0700, flock für Lesen/Ändern/Schreiben).
PHP 8.0+, Standardfunktionen; keine Datenbank oder externe Bibliothek.
`health.php` gibt nur boolesche Bereitschaftswerte zurück.

- PC-Kennung: zufällige 128 Bit; PC-Schlüssel: 256 Bit.
- Einmaliger Kopplungscode: 32 Bit, fünf Minuten, Rate-Limit für Fehlversuche.
- Handy-Schlüssel: 256 Bit, erneutes Koppeln ersetzt ihn.
- Schlüssel serverseitig als SHA-256, Vergleiche mit hash_equals.
- POST/JSON, kein CORS, Cross-site Requests abgewiesen; keine Schlüssel in URLs.
- Exakte Aktionsliste, Längenlimits, Zustandsprüfung auf dem PC.
- Jeder Auftrag hat eine ID, Kontext, kurze Lebensdauer und Bestätigung.
- Der PC quittiert Aufträge erst nach Verarbeitung. Wiederholungen derselben ID
  werden dedupliziert. Nach einem Neuladen passt der pausierte Zustand nicht zu
  einer zuvor gesendeten Aktion; diese muss am Handy neu gewählt werden.
- Spielpausen, Verbindungsabbruch und abgelaufene Szenen sperren/verwerfen Aktionen.
- Eine Sitzung pro PC-Tab, ein gekoppeltes Handy pro Sitzung.

## Dialog und Audio

Vorgegebene deutsche Dialoge werden für die englische Auswahl mit einer festen
Tabelle übersetzt. Keine Textgenerierung, Spracherkennung oder KI-API.
Sprachausgabe nutzt optional SpeechSynthesis; verfügbare Stimmen hängen vom
Browser/Betriebssystem ab. en-IN wird bei Verfügbarkeit bevorzugt.
Die UI zeigt ausdrücklich Antwortknöpfe und die Abhängigkeit von Gerätestimmen.

## Bereitstellung

Der Inhalt von public/ kommt in den Domain-Webordner. Alle Assets tragen eine
Release-Kennung, um alte JavaScript-Versionen nach dem Update zu vermeiden.
PHP-Sitzungen sind temporär; der dauerhafte Spielstand bleibt am PC.
Ohne PHP funktioniert das bestehende Ein-Gerät-Spiel weiterhin.
