Automatischer Push: 14 Datei(en) geändert

- .vault-tools/trading-plattform-pruefung/LIESMICH.md
- .vault-tools/trading-plattform-pruefung/bremse_echtlauf.py
- .vault-tools/trading-plattform-pruefung/browser_w.py
- .vault-tools/trading-plattform-pruefung/generalprobe_echtlauf.py
- .vault-tools/trading-plattform-pruefung/ha_aktiv_setzen.py
- .vault-tools/trading-plattform-pruefung/handelstag_auswertung.py
- .vault-tools/trading-plattform-pruefung/hausmelder_echtlauf.py
- .vault-tools/trading-plattform-pruefung/killswitch_simulation.py
- .vault-tools/trading-plattform-pruefung/killswitch_simulation_mutanten.py
- .vault-tools/trading-plattform-pruefung/latenz_auswertung.py
- .vault-tools/trading-plattform-pruefung/s1_alpaca_lesen.py
- .vault-tools/trading-plattform-pruefung/s5_echtlauf.py
- … und 2 weitere

Erzeugt vom PostToolUse-Hook .vault-tools/auto-push/auto_push.py.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Pascal MichelandClaude Opus 5 committed 2026-09-22 04:00:01 +02:00
1 parent 246af19683
commit 593acdd122
14 files changed
+2090 -5

No files matched your search

@@ -26,12 +26,12 @@ Koordinator-Werkzeuge, nicht fürs Repo. Sie starten **nie** den echten Broker:
| Datei | Was sie tut | Aufruf |
|---|---|---|
| `start_probe_zugang.py` | die echte App mit Attrappe, Wegwerf-Register und Wegwerf-Zugang (Benutzer `probe`, bekanntes Passwort, TOTP-Beispielgeheimnis der RFC-Literatur; beides in `zugang.json` der Ablage), auf Wunsch mit einer Paper-Statusdatei | aus dem Projektordner in WSL: `PYTHONPATH=. python start_probe_zugang.py <port> <ablage> [mit-paperstatus]` |
| `start_probe_zugang.py` | die echte App mit Attrappe, Wegwerf-Register und Wegwerf-Zugang (Benutzer `probe`, bekanntes Passwort, TOTP-Beispielgeheimnis der RFC-Literatur; beides in `zugang.json` der Ablage), auf Wunsch mit einer Paper-Statusdatei. **Seit 2026-09-21 bricht es ab, wenn im Arbeitsordner eine `config/secrets.toml` liegt** — `erzeuge_app` startete bis Paket S5 immer den echten Stille-Wächter, und eine Probe-Instanz im echten Projektordner hätte nach 180 s aufs Telefon geklingelt | aus einer **Kopie** des Projektordners (ohne Geheimnisdatei) in WSL: `PYTHONPATH=. python start_probe_zugang.py <port> <ablage> [mit-paperstatus]` |
| `angriffe.py` | 56 Fälle gegen Host-Positivliste, Origin, Sitzungszwang, Cookie-Attribute, Bremse, CSP und die anderen Header, WebSocket ohne Sitzung; Regressionsnachweis gegen das Backend vor Teil B: 45 rot | `python angriffe.py <basis-url> <ablage-mit-zugang.json>` |
| `browserlauf_zugang.py` | Anmeldeformular ohne Sitzung, falsche und richtige Anmeldung (frischer TOTP-Code), Name und „Abmelden" in der Kopfzeile, Strom, Karte „Paper-Betrieb", alle Ansichten unter der CSP, Abmelden und Neuladen, 375 px; protokolliert jede Antwort ab 400 mit Phase und Pfad (`antworten-ab-400.json`); `--sabotage` muss rot enden; Screenshots — **ansehen** (der Lauf fand so das `GET /api/paper` vor dem Tor und die unbeschrifteten Felder) | `python -X utf8 browserlauf_zugang.py http://localhost:<port> <ablage>/zugang.json <ausgabeordner> [--sabotage]` |
| `pruef_beobachtung_echt.py` | `baue_beobachtung` gegen `NautilusEnv._beobachtung` auf den echten IEX-Kerzen eines Tages, beide Seiten unabhängig gerechnet; Sabotage rot. Seit 2026-09-18 mit zweitem Teil: eine feste Aktionsfolge über alle fünf Stufen, Vergleich nach jedem Schritt bei gleichem Zustand (gemessen am 2026-09-17: 120 Beobachtungen bitgleich, davon 50 long, 50 short, Kontowert in allen ungleich dem Startkapital, Zähler in 60 größer null); `--mutant-vorzeichen` (Betrag statt Vorzeichen der Position) lässt genau die 50 Short-Beobachtungen rot fallen, während der erste Teil grün bleibt | `PYTHONPATH=. python pruef_beobachtung_echt.py JJJJ-MM-TT` aus dem Projektordner |
| `lies_paper_protokoll.py` | fasst ein Paper- oder Probe-Protokoll zusammen (Takte je Phase, Killswitch je Takt, frische Kerzen, erste Entscheidung, Orders, Schlussphase, Ende) | `python lies_paper_protokoll.py <jsonl>` |
| `handelstag_auswertung.py` | wertet einen Paper-Handelstag aus: Takte je Phase, frische Kerzen, Spanne Taktzeile gegen Minutenende (Obergrenze für „Kerze abrufbar"), Orders, Ende; mit `--broker` lesend die Orders des Paper-Kontos (Füllzeit aus `submitted_at`/`filled_at` gegen `order_timeout_s`, Vorzeichen offener Positionen), mit `--kerzen` die Kosten je Order gegen den Schluss der letzten abgeschlossenen IEX-Kerze in Basispunkten. Am 2026-09-18 an den zwei Protokollen der Nacht erprobt (Probe: Spanne ausgelassen, weil die Kerzen gespielt sind) | aus dem Projektordner: `python handelstag_auswertung.py <protokoll.jsonl> [--broker] [--kerzen]` |
| `handelstag_auswertung.py` | wertet einen Paper-Handelstag aus: Takte je Phase, frische Kerzen, Spanne Taktzeile gegen Minutenende (Obergrenze für „Kerze abrufbar"), Orders, Ende; mit `--broker` lesend die Orders des Paper-Kontos (Annahme bis Füllung aus `created_at`/`filled_at` gegen `order_timeout_s`, dazu die Teilspannen bis `submitted_at` und von dort bis zur Füllung — seit dem ersten Handelstag, an dem der Broker eine Order 8,7 s zwischen Annahme und Weitergabe liegen ließ und `submitted_at` allein das verschwiegen hätte; ein Hinweis ab der halben Grenze; Vorzeichen offener Positionen), mit `--kerzen` die Kosten je Order gegen den Schluss der letzten abgeschlossenen IEX-Kerze in Basispunkten. Am 2026-09-18 an den zwei Protokollen der Nacht erprobt (Probe: Spanne ausgelassen, weil die Kerzen gespielt sind) | aus dem Projektordner: `python handelstag_auswertung.py <protokoll.jsonl> [--broker] [--kerzen]` |
| `vorstart_pruefung.py` | liest vor dem Runner-Start: läuft schon ein Runner, Killswitch-Zustand im Register (nur Auskunft — der Start stellt nach der Neustartregel immer auf `angehalten`; ein Befund ist allein `gesperrt`), Paper-Konto glatt, Marktuhr des Brokers, eigene Uhr gegen den `Date`-Kopf des Brokers. Am 2026-09-18 fand der erste trockene Lauf einen Killswitch auf `aktiv` (Klick um 08:55 Uhr), den der Start überschreibt | aus dem Projektordner: `python vorstart_pruefung.py` |
| `runner_stand.py` | zeigt den Stand eines laufenden Paper-Runners aus seinem Protokoll: Zeilen je Art, Takte je Phase und Killswitch-Zustand, letzter Takt, Order- und Ende-Zeilen. Urteilt nicht und gibt keine Kontowerte aus. Am 2026-09-18 am Protokoll der Nacht erprobt (drei Zeilen: `kopf`, `ereignis`, `ende`); an einem Protokoll mit Takten noch nicht | in WSL: `python runner_stand.py [<protokoll.jsonl>]`, ohne Angabe das neueste `*-paper.jsonl` im Projektordner |
| `protokoll_vergleich.py` | vergleicht zwei JSONL-Protokolle der Messwerkzeuge Wert für Wert (Bitgleichheit nach einem Umbau); trennt `ABWEICHUNG`, `NUR NEU` (neuer Schlüssel, kein Befund ohne `--streng`) und `NUR ALT`. Erprobt am 2026-09-18: Selbstvergleich 5.190 Werte ohne Befund, `--sabotage` (ein ULP) rot, der Ein-Jahres-Lauf mit `OMP_NUM_THREADS=8` gegen den ohne 621 Abweichungen ab der dreizehnten Stelle | `python protokoll_vergleich.py <alt.jsonl> <neu.jsonl> [--ohne …] [--streng] [--sabotage]` |
@@ -58,6 +58,27 @@ Koordinator-Werkzeuge, nicht fürs Repo. Sie starten **nie** den echten Broker:
|---|---|---|
| `ha_einrichten.py` | richtet in Home Assistant die Gegenstelle für den Hausmelder ein: acht Helfer mit dem Präfix `trading_` und eine Automation mit Webhook-Auslöser (`local_only`, nur POST). Die Webhook-ID entsteht im Skript (64 Hex-Zeichen), wird nie ausgegeben und landet nur in `[homeassistant]` der `config/secrets.toml` des Trading-Projekts, mit `aktiv = false`. `pruefen` und `lesen` lesen nur (`lesen` zeigt zusätzlich die Zustände der Helfer), `probe` schickt eine Beispiel-Nutzlast und liest zurück, `entfernen` baut Helfer und Automation wieder ab. **Läuft unter Windows mit dem Python des Home-Assistant-Projekts** — dort liegen der Klient `src/ha_verbindung.py`, die Adresse der Instanz und der Name der Token-Variable; das Token bleibt auf der Windows-Seite und kommt nie auf den Trading-Rechner. Gemessen am 2026-09-20/21: eingerichtet, `probe` rückgelesen wie gesendet, und ein POST des echten `Hausmelder` aus WSL kam in den Helfern an | `<ha-projekt>\.venv\Scripts\python.exe -X utf8 ha_einrichten.py <pruefen|lesen|einrichten|probe|entfernen> "<ha-projekt>" "<trading-projekt>"` |
## Nacht vom 2026-09-20 auf den 2026-09-21: Generalprobe, Hausmelder, YubiKey, Härtung
| Datei | Was sie tut | Aufruf |
|---|---|---|
| `generalprobe_echtlauf.py` | ruft die **echte** Funktion `_generalprobe` aus `scripts/paper.py` — dieselbe Verdrahtung wie im Betrieb — mit den echten IEX-Kerzen eines Tages (JSON aus `hole_kerzen.py`), einer Sicherungskopie des Registers (das echte wird nur lesend geöffnet), dem echten Registermodell, einem mitschreibenden „echten" Konto, das bei jedem schreibenden Aufruf wirft, einer Netzsperre auf `requests.Session.request` und einem Faden, der wie das Dashboard klickt (fortsetzen, anhalten, fortsetzen, glattstellen, freigeben). Urteilt über Exit-Code, Modus, Meldungsvorsatz, Netzversuche, Aufrufe am Konto, Position nach dem Glattstellen, Alter des Herzschlags, `tagesstart.json`. Gemessen am 2026-09-20/21 mit den Kerzen des 2026-09-18: bei 1 s je Marktminute 435 s, 389 Takte, drei Orders, 0 Befunde | in WSL: `python generalprobe_echtlauf.py <code-baum> <echter-projektordner> <kerzen.json> <wegwerf-ordner> [tempo]` |
| `hausmelder_echtlauf.py` | der echte `Hausmelder`-Faden gegen einen mitschreibenden HTTP-Server auf `127.0.0.1`: erste Nutzlast ohne Statusdatei, Änderung, Stille ohne Änderung, Lebenszeichen, Killswitch-Wechsel, HTTP 500 (Merker kippt nicht), 302 (nicht gefolgt), `veraltet`, Adresse in keinem Fehlschlag und keinem `repr`, `starte_hausmelder` über eine Geheimnisdatei. Mit `--echt <secrets.toml>` zusätzlich **ein** POST an die dort eingetragene Adresse; die Adresse wird nie ausgegeben. Zurücklesen mit `ha_einrichten.py lesen` | in WSL: `python hausmelder_echtlauf.py <code-baum> <wegwerf-ordner> [--echt <secrets.toml>]` |
| `ha_aktiv_setzen.py` | setzt `[homeassistant] aktiv` in einer Geheimnisdatei auf `true` oder `false` — genau eine Zeile, mit Probe vor dem Schreiben, dass sich nur dieser Wert ändert; gibt nur Abschnittsnamen und die Länge der Adresse aus | `python ha_aktiv_setzen.py <secrets.toml> <true|false>` |
| `start_probe_w.py` | Probe-Backend wie `start_probe_zugang.py`, dazu die Konfiguration für Sicherheitsschlüssel (RP-ID `localhost`, Origin `http://localhost:<port>`) und wahlweise ein nur gelesener Marktkatalog. **Bricht ab, wenn im Arbeitsordner eine `config/secrets.toml` liegt** — Probe-Instanzen starten nur aus einer Kopie oder einem Arbeitsbaum ohne Geheimnisse, sonst sprächen sie mit dem echten ntfy und dem echten Home Assistant | in WSL aus der Kopie: `python start_probe_w.py <port> <ablage> [<katalog>]` |
| `browser_w.py` | Browserlauf zum YubiKey-Weg: Playwright/Chromium mit einem **virtuellen Authenticator** über das DevTools-Protokoll (`WebAuthn.addVirtualAuthenticator`) gegen die Probe-Instanz unter `http://localhost:<port>` — Anmelden mit Code, Registrieren in „Zugang", Anmelden mit Passwort und Schlüssel (der Zähler des Authenticators muss steigen, sonst wurde er nie gefragt), falsches Passwort, Code-Weg danach, Entfernen, Gegenprobe unter `127.0.0.1` (409), Schlüsseldatei und Anmeldeprotokoll ohne Passwort, keine CSP- oder Permissions-Policy-Meldung. Gemessen am 2026-09-21: 17 von 17, auch gegen eine gehärtete Systemeinheit | unter Windows: `python -X utf8 browser_w.py <port> <ablage>` |
| `latenz_auswertung.py` | rechnet Reaktionszeiten aus dem, was ein Lauf ohnehin hinterlässt — nur lesend, Register mit `mode=ro`: Klick → Runner reagiert (Ereignis in `killswitch_ereignisse` mit Auslöser `pascal` gegen die erste Taktzeile mit dem neuen Zustand; obere Schranke, weil die Taktzeile am Ende des Takts entsteht), Kerze → Taktende (nur im Modus `paper`) und den Taktabstand als Rahmen. Für Tage, an denen der Runner seine Latenzen noch nicht selbst misst. Gibt nie einen Kontowert aus | in WSL aus dem Projektordner: `python latenz_auswertung.py <protokoll.jsonl> [<register.db>]` |
| `bremse_echtlauf.py` | Misst das Wachstum des Anmeldeprotokolls im gesperrten Zustand gegen eine laufende Probe-Instanz: fünf Fehlversuche, dann je 5 s Dauerfeuer auf `beginn`, `abschluss` und den Weg mit Code, gezählt in Zeilen und Bytes; zweiter Durchgang mit dem Abschluss als erster gesperrter Anfrage; dazu der 409 des Abschlusses unter `127.0.0.1`. Anlass: Der Prüfer maß am 2026-09-21 im Schlüsselweg 22 474 B/s, weil die Protokollbremse nur im Weg mit Code stand. Nach Task 229 gemessen: 2721 Anfragen in 5 s → eine Zeile | in WSL: `python bremse_echtlauf.py <port> <ablage> <beginn\|abschluss>` |
| `s5_echtlauf.py` | Gegenmessung der Dashboard-Härtung gegen eine laufende Probe-Instanz: 422 ohne die Eingabe, 512 MiB Rumpf mit und ohne `content-length` samt Spitzenspeicher des Servers aus `/proc`, Latenz von `POST /api/killswitch/anhalten` unter 40 parallelen teuren Kerzenabrufen, überlanger Grund, Sitzungswiderruf nach Passwortwechsel. Gemessen am 2026-09-21: 413 in 0,19 s ohne Speicherzuwachs (vorher 1,5 GiB), Killswitch höchstens 0,51 s (vorher 118 s) | in WSL: `python s5_echtlauf.py <port> <ablage> <code-baum>` |
| `s1_alpaca_lesen.py` | liest mit dem Alpaca-Klienten eines Code-Baums die echten Antworten des Paper-Kontos — **nur lesend, ohne einen Betrag auszugeben** (Feldnamen, Typen, Statusverteilung der Orderhistorie, Felder mit `None`). Für den Vergleich alter gegen neuer Parser | in WSL: `python s1_alpaca_lesen.py <code-baum> <echter-projektordner>` |
## Killswitch-Simulation (2026-09-21)
| Datei | Was sie tut | Aufruf |
|---|---|---|
| `killswitch_simulation.py` | der Killswitch im Zeitraffer, **ohne Netz, ohne das echte Konto und ohne das echte Register** — die echte Funktion `_generalprobe` mit den Kerzen eines Tages (JSON aus `hole_kerzen.py`), verdrahtet wie `generalprobe_echtlauf.py`. Drei Szenarien: `hand` (fortsetzen, anhalten, fortsetzen, glattstellen, freigeben — gehandelt wird nur im Zustand `aktiv`, beim Anhalten bleibt die Position stehen, nach dem Glattstellen ist sie null und der Runner gesperrt), `sturz` (alle Kerzen ab 11:00 Uhr New Yorker Zeit zehn Prozent tiefer — der Runner reißt die Tagesverlustgrenze selbst, stellt glatt, sperrt, meldet „Grenze verletzt", und sperrt nach einem „Freigeben" im selben Takt wieder, ohne neue Order) und `neustart` (das Dashboard startet mitten am Tag neu — Pause mit stehender Position, Pausenmeldung mit dem Auslöser `neustart`, und die Latenzanzeige zählt den Neustart nicht als Klick). Der Kopfkommentar nennt je Prüfung die Herkunft der Erwartung und die Grenzen: Gefüllt wird gespielt, der Klick geht nicht über HTTP, der Watchdog wird nicht gezielt ausgelöst. **Anlass:** Die Killswitch-Übung des Projekts stellt echte Orders und schreibt ins gemeinsame Register — sie darf nicht laufen, solange der Paper-Runner läuft. Gemessen am 2026-09-21 gegen den Betriebscode (0.20.0) mit den Kerzen des 2026-09-18 bei 1 s je Marktminute: je Szenario 431 s, Exit 0, 389 Takte, kein Befund und kein Hinweis; Reaktion des Runners auf einen Klick 0,85 bis 0,99 s (neun Messungen) | in WSL: `python killswitch_simulation.py <hand\|sturz\|neustart> <code-baum> <echter-projektordner> <kerzen.json> <wegwerf-ordner> [tempo]` |
| `killswitch_simulation_mutanten.py` | der Regressionsnachweis dazu: kopiert den Code-Baum, fährt zuerst die Grundlinie, macht die Kopie dann an sechs Stellen einzeln kaputt (Runner übergeht den Killswitch; Glattstellen schließt nicht; Tagesverlustgrenze greift nicht; jeder Auslöser zählt als Klick; keine Pausenmeldung beim Neustart; Tagesverlust hält nur an) und erwartet je Mutant Exit 2. Ein Muster, das nicht genau einmal trifft, ist ein Befund des Treibers. In zwei Teilen, je unter zehn Minuten. Gemessen am 2026-09-21 gegen den Betriebscode: Grundlinie und Gegenprobe in allen drei Szenarien ohne Befund, alle sechs Mutanten gesehen — drei davon an genau einer Prüfung (die Position nach dem Glattstellen, die Zahl der Klick-Messungen, die fehlende Pausenmeldung). **Der erste Lauf der Grundlinie fand dabei einen Fehler der Prüfung, nicht des Runners:** Im Schnelltempo fiel ein Klick mitten in einen Takt; dessen Taktzeile trug schon `gesperrt`, aber noch die Phase `handelt`, ohne Entscheidung und ohne Order. Seitdem ist alles ab dem zweiten Takt eines nicht aktiven Abschnitts verbindlich, der erste wird als Hinweis gedruckt | in WSL: `python killswitch_simulation_mutanten.py <code-baum> <echter-projektordner> <kerzen.json> <arbeitsordner> <1\|2>` |
Das Einrichten selbst (`deploy/dienste-einrichten.sh` unter `sudo -S`, `deploy/windows/wsl-wachhalten.ps1 -Aktion einrichten`) und das Eintragen des ntfy-Themas liefen aus dem Scratchpad der Sitzung; die Befehle stehen in der Administrator-Anleitung des Projekts, Abschnitt „Produktivbetrieb als Dienst".
Die Compose-Probe (Bauen aus dem echten Baum mit verankerten Ausschlüssen, Start, Healthcheck, Angriffsfälle, Runner-Probe im Container, Aufräumen) lag als `compose_probe_echt.sh` im Scratchpad der Sitzung und braucht `sudo -S` mit dem WSL-Passwort aus `$WSL_PW`; sie ist deshalb nicht hier abgelegt. Muster: `tar --exclude=./data` — ohne Anker fällt auch `trading/data` weg.