Testen laeuft jetzt ueber das Deploymentcenter; Befunde in den Bugtracker
CI / Build & Tests (Linux) (push) Canceled after 0s
CI / Plattformneutralität & Hygiene (push) Canceled after 0s

Die Testanleitung im PolyTrader-Repo ist nur noch ein Zeiger auf die
massgebliche Fassung in Deploymentcenter/docs/TESTUMGEBUNG.md, plus dem, was
PolyTrader-eigen ist: Display :99, Datenbank polytrader_test, Dienstkonto,
Publish-Verzeichnis, /tmp-Praefix. Die Anleitung galt immer projektuebergreifend
und lag nur hier, weil sie beim ersten Linux-Lauf von PolyTrader entstand. Eine
Tabelle loest die alten Abschnittsnummern auf, damit vorhandene Verweise lesbar
bleiben.

Befundbericht: Nachtrag 6 haelt die Gegenprobe am Bild vom 28.08.2026 fest -
den ersten Lauf nach dem neuen Verfahren. Linux-Build 0 Fehler / 15 Warnungen
wie unter Windows, 484 Tests gruen, --smoke-ui unter xvfb-run -n 99 durchgaengig
gruen. B-6, B-7, B-11, B-13, B-14 und die B-12-Selbstheilung sind damit auf der
Zielplattform bestaetigt; B-9 hat sich als kein Fehler entpuppt, und die
Spaltenumstellung hatte einen eigenen Fehler erzeugt.

Damit ist dieser Bericht abgeschlossen. Was offen bleibt, steht ab jetzt im
Bugtracker (Items #50-#52 und #56 fuer polytrader, #53-#55 und #57 fuer
deploymentcenter) statt in Befundberichten - dort geht es nicht mehr verloren,
und Befunde an fremden Projekten landen dort, wo jemand sie beheben kann.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Richard
2026-08-28 21:06:34 +02:00
co-authored by Claude Opus 5
parent 57cfca5fe9
commit 53231d62bc
3 changed files with 196 additions and 382 deletions
+8 -3
View File
@@ -92,8 +92,13 @@ Nebenbefund: **sämtliche Dezimal-Einstellungen waren in der Oberfläche nicht m
also die komplette Risikokonfiguration. Einzelheiten und Begründungen im Nachtrag 5 von
[BEFUND-Linux-Betrieb-2026-08-26.md](./pruefplaene/BEFUND-Linux-Betrieb-2026-08-26.md).
⬜ **Offener Rest:** Gegenprobe am Bild auf der VM (Spaltenbreiten mit echten Daten,
Kalendersymbol B-9, Splitter im Copytrading-Detailbereich). Verfahren und Testdaten stehen bereit.
**Stand 28.08.2026:** Die Gegenprobe am Bild ist gelaufen (Nachtrag 6). Alle Behebungen sind auf
der Zielplattform bestätigt; B-9 hat sich als **kein Fehler** entpuppt (Avalonia zeichnet die
heutige Tageszahl — am 26.08. eine „26", am 28.08. eine „28"), und die Spaltenumstellung hatte
einen eigenen Fehler erzeugt, der ebenfalls behoben ist.
⬜ **Offener Rest:** Splitterpositionen und Leerzustände im Gebrauch beurteilen. Alles Weitere
steht ab jetzt im **Bugtracker** (Items #50–#57), nicht mehr in Befundberichten.
**Blockiert nichts** — aber es ist die letzte offene Zusage der UI-Portierung.
Regeln für Nacharbeiten: [LEITFADEN-Avalonia-Portierung.md](./LEITFADEN-Avalonia-Portierung.md).
@@ -431,7 +436,7 @@ Prüfplan: [pruefplaene/PREDICTALYTICS-PRUEFPLAN-Master-Auswahl.md](./pruefplaen
| | Punkt | Details |
|---|---|---|
| **T1** | ⬜ 15 Build-Warnungen | Alle im Avalonia-Projekt: 13 × `CS8618` (Felder in Fenster-Konstruktoren), 1 × `CS8848` (Vorrang bei `switch`), 1 × `CS8602` (möglicher Nullverweis, `PdfExporter.cs:40`). Die letzten beiden sind einen Blick wert — dahinter kann ein echter Fehler stecken. Erst wenn sie weg sind, ist `-warnaserror` in der CI sinnvoll |
| **T2** | ⬜ TerminalLogger | Stempelt mit `DateTime.Now` statt der konfigurierten `AppTimeZone`. Auf einem UTC-Linuxserver passen die Logdatei-Grenzen nicht zur angezeigten Uhrzeit. Zusammen mit der Umstellung auf `Microsoft.Extensions.Logging` erledigen — **bei A4a nachweisbar** |
| **T2** | ⬜ TerminalLogger | **Zeitzonen-Teil am 27.08.2026 erledigt** (vorgezogen, weil A4a den Fehler nachgewiesen hat): Zeitstempel sind jetzt `DateTimeOffset` in der Anzeige-Zeitzone, Logdatei-Grenzen und Oberfläche passen zusammen, und die `.log`-Dateien heißen wie die `.jsonl` (`yyyy-MM-dd`). **Offen bleibt** die eigentliche Umstellung auf `Microsoft.Extensions.Logging` |
| **T3** | ⬜ God-Methoden | `PollLiveAccountsAsync`, `ProcessAccountOrderAsync` splitten; duplizierte Closed-Trade-Erzeugung zentralisieren |
| **T4** | ⬜ CopyTrading-Follow-ups | TradeId-Autoincrement, Dedup, Performance |
| **T5** | ⬜ Barlow-Schriften | Im UI-Redesign vorgesehen, nie eingebettet |
+83 -374
View File
@@ -1,389 +1,98 @@
# Linux-Testumgebung (gemeinsam genutzte VM)
# Linux-Testumgebung — PolyTrader-Teil
**Stand: 26.08.2026** · Eingerichtet beim ersten Linux-Lauf von PolyTrader (Roadmap A4a).
**Stand: 28.08.2026**
> **Diese Anleitung gilt projektübergreifend.** Sie richtet sich an alle Agenten und Entwickler,
> die auf der VM testen — nicht nur an PolyTrader. Die maßgebliche Fassung liegt auf der Maschine
> selbst unter **`~/TESTUMGEBUNG.md`**; dieses Dokument im PolyTrader-Repo ist die versionierte
> Kopie. Wer etwas an der Umgebung ändert, zieht **beide** nach.
> ## ⚠️ Die Anleitung ist umgezogen
>
> Die vollständige, gepflegte Fassung liegt jetzt im **Deploymentcenter-Repo**:
>
> **`J:\Softwareprojekte\Deploymentcenter\docs\TESTUMGEBUNG.md`**
>
> Diese Datei hier enthält nur noch, was **PolyTrader-eigen** ist.
**Warum der Umzug.** Die Anleitung galt von Anfang an projektübergreifend — sie regelt
Datenbanknamen, X-Displays und Portvergabe für *alle* Projekte auf der geteilten VM. Sie lag
trotzdem im PolyTrader-Repo, weil sie beim ersten Linux-Lauf von PolyTrader entstanden ist.
Das war die falsche Heimat, und es fiel auf, als die Testumgebung an die vorhandene Infrastruktur
angeschlossen wurde: Lizenzschlüssel, Release-Ablage und Bugtracker gehören dem Deploymentcenter,
und die Beschreibung, wie ein Agent sie benutzt, gehört dorthin, wo sie mit ihnen gemeinsam
gepflegt wird. Ein Agent in Predictalytics hätte die Regeln für sein X-Display sonst in einem
fremden Handelsprojekt suchen müssen.
---
## 1. Was diese Maschine ist
## Was neu ist
Eine Ubuntu-Desktop-VM zum **Testen** — nicht für Produktivbetrieb, nicht für echte Zugangsdaten,
nicht für Geld bewegende Läufe.
Auf der VM muss nichts mehr von Hand besorgt werden, was das Deploymentcenter schon hat:
| | |
```bash
curl -fsSL https://dc.mhdf.de/testkit/dc-testkit.sh -o ~/bin/dc-testkit && chmod +x ~/bin/dc-testkit
dc-testkit doctor # Werkzeuge, Netz, Token, Projekt
dc-testkit license # befristeten DEV-Lizenzschlüssel selbst holen
dc-testkit run # ausliefern, prüfen, aktualisieren — meldet, was scheitert
dc-testkit report --type bug --title "…" --desc "…"
```
Voraussetzung ist ein **Werkbank-Token** für PolyTrader (Besitzerart `dev_agent`, Rechte
`bugtracker:manage` und `license:dev`). Das legt ein Mensch einmalig im Deploymentcenter-WebUI an;
siehe `TESTUMGEBUNG.md` §4.2.
**Kein Kundenschlüssel mehr auf der Test-VM.** Ein DEV-Schlüssel läuft nach 30 Tagen ab, ist in
der Aktivierungsliste als Testhardware erkennbar und verbraucht keine Aktivierungsplätze einer
echten Lizenz.
---
## PolyTrader-eigene Festlegungen
Diese Werte stehen auch in der Belegungsliste der Hauptanleitung (§7); hier stehen sie, damit man
sie beim Arbeiten am Projekt nicht dort suchen muss.
| Was | Wert |
|---|---|
| System | Ubuntu 26.04 LTS, Kernel 7.0, x86_64 |
| Ausstattung | 31 GB RAM, 5 CPUs, ~33 GB freier Plattenplatz |
| Erreichbar | `192.168.40.48` über einen WireGuard-Tunnel |
| Benutzer | `richard` |
| Besonderheit | **Desktop-Umgebung vorhanden** — grafische Anwendungen sind testbar, nicht nur Dienste |
| X-Display | **`:99`** — fest für PolyTrader |
| Datenbank | `polytrader_test`, Benutzer `polytrader_test`@`localhost` |
| Passwortdatei | `~/.polytrader_test_dbpw` (Rechte 600) |
| systemd-Unit | `polytrader.service`, Konto `polytrader`, Verzeichnis `/opt/polytrader` |
| Publish-Verzeichnis | `~/polytrader-test` |
| Dateien in `/tmp` | immer mit Präfix `polytrader_` |
| Fenstername für `xdotool` | `^PolyTrader$` |
**Warum eine Desktop-VM?** Weil sich damit beides prüfen lässt: der kopflose Serverbetrieb
(systemd) *und* die grafische Oberfläche auf der Zielplattform.
⚠️ **`xvfb-run -n 99`, niemals `-a`.** Das `-a` sucht sich selbst ein freies Display und beginnt
dabei bei `:99` — also ausgerechnet auf PolyTraders Nummer.
⚠️ **Keine Produktivdatenbank verbinden.** Der `MarketSyncService` synchronisiert selbständig
Marktdaten, sobald er läuft — auch dann, wenn niemand ihn darum gebeten hat.
---
## 2. Zugang einrichten
## Wo die alten Abschnitte jetzt stehen
Der Zugang läuft über **SSH-Schlüssel**. Passwort-Anmeldung wird nicht verwendet — Agenten geben
grundsätzlich keine Passwörter ein.
Ältere Dokumente in diesem Repo verweisen auf Abschnittsnummern dieser Datei. Die Nummerierung hat
sich durch den neuen Testkit-Abschnitt verschoben:
### 2.1 Schlüssel erzeugen (auf dem eigenen Rechner)
```bash
ssh-keygen -t ed25519 -f ~/.ssh/testvm_<projekt> -N "" -C "<projekt>@testvm"
```
Ein **eigener Schlüssel je Projekt** — dann lässt sich einzelnen Projekten der Zugang entziehen,
ohne alle anderen auszusperren.
### 2.2 Öffentlichen Schlüssel hinterlegen
Der Inhalt von `~/.ssh/testvm_<projekt>.pub` wird auf der VM in `~/.ssh/authorized_keys`
eingetragen. **Das muss ein Mensch tun** (einmalig, mit Passwort). Direkt auf der VM:
```bash
mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo '<INHALT DER .pub-DATEI>' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys
```
### 2.3 SSH-Konfiguration (auf dem eigenen Rechner)
```
Host testvm
HostName 192.168.40.48
User richard
IdentityFile ~/.ssh/testvm_<projekt>
IdentitiesOnly yes
ServerAliveInterval 30
ServerAliveCountMax 4
```
⚠️ **Kein `ControlMaster`/`ControlPath` eintragen, wenn der Client unter Windows läuft** —
Windows-OpenSSH unterstützt Verbindungs-Multiplexing nicht und scheitert mit
„Failed to connect to new control master". Stattdessen mehrere Prüfschritte pro Aufruf bündeln.
Test: `ssh testvm "hostname"`
---
## 3. Was installiert ist
| Werkzeug | Version | Anmerkung |
|---|---|---|
| .NET SDK | 10.0.111 (Runtime 10.0.11) | SDK, nicht nur Runtime — auf der VM kann gebaut werden |
| MariaDB | 11.8.6 | Dienst `mariadb`, lauscht auf `localhost:3306` |
| Git | 2.53.0 | |
| Xvfb | vorhanden | Virtueller Framebuffer für GUI-Tests ohne Bildschirm (siehe 4.7) |
| xdotool | vorhanden | Klicks und Tastatureingaben skripten |
| ImageMagick | vorhanden | `import` für Bildschirmaufnahmen, `convert` zum Zuschneiden |
| JetBrains Rider | vorhanden | |
| Docker | **nicht** installiert | |
| Node.js | **nicht** installiert | |
**Nicht vorhandene Werkzeuge dürfen installiert werden** — aber bitte in der Belegungsliste
(Abschnitt 6) vermerken, damit andere wissen, was sich geändert hat.
---
## 4. Konventionen für mehrere Projekte
Die Maschine wird von mehreren Projekten geteilt. Diese Regeln verhindern, dass sich Tests
gegenseitig zerstören:
### 4.1 Datenbanken — je Projekt eine eigene
**Niemals** eine fremde Datenbank mitbenutzen und **niemals** eine Produktivdatenbank verbinden.
```bash
# Passwort erzeugen und ablegen (nur für den Besitzer lesbar)
PW=$(openssl rand -base64 18 | tr -d "/+=" | head -c 20)
echo "$PW" > ~/.<projekt>_test_dbpw && chmod 600 ~/.<projekt>_test_dbpw
sudo mariadb -e "CREATE DATABASE IF NOT EXISTS <projekt>_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '<projekt>_test'@'localhost' IDENTIFIED BY '$PW';
GRANT ALL PRIVILEGES ON <projekt>_test.* TO '<projekt>_test'@'localhost';
FLUSH PRIVILEGES;"
```
| Was | Schema | Beispiel |
|---|---|---|
| Datenbank | `<projekt>_test` | `polytrader_test` |
| Benutzer | `<projekt>_test`@`localhost` | `polytrader_test` |
| Passwortdatei | `~/.<projekt>_test_dbpw` (Rechte 600) | |
Die Rechte enden **an der eigenen Datenbank** — `GRANT ALL ON <projekt>_test.*`, nie global.
### 4.2 Verzeichnisse
| Zweck | Ort |
| Alt (hier) | Neu (`Deploymentcenter/docs/TESTUMGEBUNG.md`) |
|---|---|
| Quellcode | `~/RiderProjects/<projekt>` |
| Publish/Testlauf im Benutzerkontext | `~/<projekt>-test` (voller Projektname, keine Kürzel) |
| Installation als Dienst | `/opt/<projekt>` |
### 4.3 systemd-Dienste
Unit-Name = Projektname: `<projekt>.service`. Eigenes Dienstkonto je Projekt:
```bash
sudo useradd --system --home-dir /opt/<projekt> --shell /usr/sbin/nologin <projekt>
```
Nach dem Test **abschalten** (Abschnitt 7) — sonst laufen irgendwann fünf Dienste, die niemand
mehr zuordnen kann, und der nächste Test misst gegen fremde Last.
### 4.4 Ports
Vor dem Belegen prüfen: `ss -tlnp`. Belegte Ports stehen in Abschnitt 6. Wer einen Port dauerhaft
belegt, trägt ihn dort ein.
### 4.5 X-Displays — feste Nummer je Projekt
Damit **mehrere Agenten gleichzeitig** Oberflächen testen können, bekommt jedes Projekt ein
eigenes virtuelles Display. Zwei Prozesse auf demselben Display sehen die Fenster des jeweils
anderen — Klicks landen im falschen Programm, Aufnahmen zeigen fremde Anwendungen.
| Display | Projekt |
|---|---|
| `:99` | **PolyTrader** |
| `:98` | **Predictalytics** |
| `:97` | **ClawdDotNet** |
| `:96` | **IBKRTrader** |
| `:95` und **absteigend** | künftige Projekte (nächstes freies von oben nach unten) |
Wer ein neues Projekt aufnimmt, trägt seine Nummer in die Belegungsliste (Abschnitt 6) ein.
**Belegte Displays prüfen:**
```bash
ls /tmp/.X11-unix/ # X0 = der echte Desktop, X99 = PolyTrader usw.
pgrep -a Xvfb # zeigt, welcher Xvfb auf welchem Display läuft
```
**Verwaiste Sockets** — beide Befehle gemeinsam lesen: Steht in `/tmp/.X11-unix/` ein `X98`, zu
dem `pgrep` keinen Prozess zeigt, ist das ein Überbleibsel eines abgestürzten oder hart beendeten
Xvfb. Die Nummer wirkt dann belegt, obwohl sie frei ist. Aufräumen:
```bash
sudo rm -f /tmp/.X11-unix/X98
```
*(Genau so entstanden: ein `xvfb-run -a`, das sich :98 nahm, weil :99 gerade lief — siehe die
Warnung in 4.7.)*
⚠️ **Drei Regeln, damit der Parallelbetrieb wirklich trägt:**
1. **`DISPLAY` in jedem Skript setzen** (`export DISPLAY=:98`). Fehlt die Variable, landet man auf
`:0` — dem echten Desktop — und stört den Menschen, der dort gerade arbeitet.
2. **Nie `pkill Xvfb` ohne Displaynummer.** Das erschlägt die Sitzungen aller anderen Projekte.
Immer `pkill -f "Xvfb :98"`. Dasselbe gilt für die eigene Anwendung: `pkill -f` mit einem zu
allgemeinen Muster trifft fremde Prozesse — besser die gemerkte PID beenden.
3. **Dateien in `/tmp` mit Projektpräfix.** `/tmp/v_1.png` überschreibt sich gegenseitig; nimm
`/tmp/<projekt>_v_1.png`. Gleiches gilt für Logdateien und Skripte.
### 4.6 Erhöhte Rechte
`sudo` verlangt normalerweise ein Passwort. Für Testläufe kann es befristet freigeschaltet werden
(**ein Mensch, einmalig**):
```bash
echo "richard ALL=(ALL) NOPASSWD:ALL" | sudo tee /etc/sudoers.d/99-testing && sudo chmod 440 /etc/sudoers.d/99-testing
```
**Nach Abschluss wieder entfernen:**
```bash
sudo rm /etc/sudoers.d/99-testing
```
Das hebt den Schutz für das Konto vollständig auf — vertretbar auf einer Test-VM hinter VPN, aber
nicht dauerhaft und niemals auf einer Produktivmaschine.
### 4.7 GUI-Anwendungen ohne Bildschirm testen
Braucht eine Anwendung X11, scheitert sie über SSH mit `XOpenDisplay failed`. Für einen einzelnen
Durchlauf genügt:
```bash
xvfb-run -n <deine-nummer> ./MeineAnwendung --irgendein-schalter
```
⚠️ **Nicht `xvfb-run -a` verwenden.** Das `-a` sucht sich selbst ein freies Display und **beginnt
dabei bei :99** — also ausgerechnet auf PolyTraders Nummer. Läuft dort gerade nichts, belegt es
diese Nummer; startet PolyTrader kurz darauf, kollidieren beide. Mit `-n 98` (bzw. der eigenen
Nummer aus 4.5) bleibt die Zuordnung eindeutig.
### 4.8 Oberflächen selbst begutachten — ohne Bildschirm, ohne fremde Hilfe
**Ein Agent kann die Oberfläche eigenständig prüfen.** Kein Mensch muss am Bildschirm sitzen und
Bildschirmfotos schicken. Das Verfahren hat sich am 26.08.2026 bewährt und **sieben Befunde
zutage gefördert**, darunter einen, der sämtliche Tabellen der Anwendung unsichtbar machte.
Drei Werkzeuge, alle installiert: **Xvfb** (virtuelles Display), **xdotool** (Klicken und Tippen),
**ImageMagick** (`import` für Aufnahmen, `convert` zum Zuschneiden).
Anders als `xvfb-run` wird das Display hier **dauerhaft** gestartet, damit sich zwischen den
Aufnahmen navigieren lässt:
```bash
#!/bin/bash
# Kopf anpassen - das ist alles, was sich je Projekt unterscheidet:
PROJEKT="polytrader"
DISP=":99" # eigene Nummer aus Abschnitt 4.5!
FENSTER="^PolyTrader$"
cd ~/$PROJEKT-test
export DISPLAY=$DISP
pkill -f "Xvfb $DISP" 2>/dev/null; sleep 1
Xvfb $DISP -screen 0 1600x1000x24 >/dev/null 2>&1 &
sleep 3
nohup ./MeineAnwendung > /tmp/${PROJEKT}_gui.log 2>&1 &
APP=$!
sleep 25 # Startzeit großzügig bemessen
# Fenster-ID ermitteln (bestaetigt, dass die Oberflaeche ueberhaupt erscheint)
xdotool search --name "$FENSTER" | head -1
# navigieren und aufnehmen - Dateinamen mit Projektpraefix, sonst
# ueberschreiben sich parallel laufende Projekte gegenseitig
shoot() { sleep 5; import -window root /tmp/${PROJEKT}_$1.png; echo " $1"; }
shoot 1_start
xdotool mousemove 127 205 click 1; shoot 2_zweite_ansicht
xdotool mousemove 127 237 click 1; shoot 3_dritte_ansicht
kill $APP 2>/dev/null; sleep 2; pkill -f "Xvfb $DISP" 2>/dev/null
```
Danach die Bilder abholen und ansehen:
```bash
scp testvm:'/tmp/polytrader_*.png' .
```
**Was sich dabei bewährt hat:**
- **Großzügige Wartezeiten.** 25 Sekunden nach dem Start, 5 Sekunden nach jedem Klick. Wird zu
früh aufgenommen, entsteht ein halb gezeichnetes Fenster, und man sucht Fehler, die keine sind.
- **Klickpunkte aus dem ersten Bild ablesen.** Erst eine Aufnahme machen, dort die Koordinaten der
Menüpunkte bestimmen, dann das Skript damit bestücken.
- **Details vergrößern statt raten.** Bei einem Verdacht den Ausschnitt herausschneiden:
```bash
convert v_1_start.png -crop 560x130+265+540 +repage -resize 200% /tmp/detail.png
```
- **Kontraste nachmessen statt schätzen.** Ob Text lesbar ist, lässt sich ausrechnen — Pixelfarben
auslesen und das WCAG-Verhältnis bestimmen (4,5:1 für normalen Text). So wird aus „wirkt blass"
ein belegter Befund.
- **Nur eine Instanz des eigenen Projekts gleichzeitig.** Läuft der systemd-Dienst noch, schreiben
zwei Prozesse in dieselbe Datenbank und es entstehen Fehler, die nichts mit der Oberfläche zu tun
haben. Vorher `sudo systemctl stop <projekt>`. (Ein **anderes** Projekt auf seinem eigenen
Display stört dagegen nicht — dafür ist die Trennung aus 4.5 da.)
- **Auf Zeichen achten, die falsch aussehen.** Fehlt eine Icon-Schriftart, ersetzt Fontconfig sie
stillschweigend durch etwas anderes — ein Kalendersymbol wird dann zu einer sinnlosen Zahl. Das
fällt nur im Bild auf, nie im Log.
Für einen Test **mit echtem Bildschirm** kann trotzdem jemand am Desktop der VM sitzen (oder RDP
nutzen, Port 3389 ist offen) — nötig ist es für die Sichtprüfung nicht.
---
## 5. Was hier nicht passieren darf
1. **Keine Produktivdatenbank verbinden.** Hintergrunddienste schreiben oft ungefragt — bei
PolyTrader etwa synchronisiert der `MarketSyncService` selbständig Marktdaten.
2. **Keine echten Handels-/Zugangsdaten hinterlegen.** Keine privaten Schlüssel, keine
Live-API-Zugänge, keine Lizenzschlüssel für Produktivsysteme.
3. **Keine fremden Projektverzeichnisse oder Datenbanken anfassen.**
4. **Nichts Dauerhaftes hinterlassen**, was nicht in Abschnitt 6 steht.
---
## 6. Belegung (bei Änderungen fortschreiben)
**Datenbanken**
| Datenbank | Benutzer | Projekt | seit |
|---|---|---|---|
| `polytrader_test` | `polytrader_test`@localhost | PolyTrader | 26.08.2026 |
**Dienste**
| Unit | Konto | Verzeichnis | Projekt | seit |
|---|---|---|---|---|
| `polytrader.service` | `polytrader` | `/opt/polytrader` | PolyTrader | 26.08.2026 |
**Verzeichnisse**
| Projekt | Publish-Verzeichnis | Dienst |
|---|---|---|
| PolyTrader | `~/polytrader-test` | `/opt/polytrader` |
**X-Displays** (Vergabe siehe 4.5)
| Display | Projekt | Stand |
|---|---|---|
| `:0` | echter Desktop — **nie belegen** | |
| `:99` | PolyTrader | 26.08.2026 |
| `:98` | Predictalytics | reserviert |
| `:97` | ClawdDotNet | reserviert |
| `:96` | IBKRTrader | reserviert |
| `:95` abwärts | frei für künftige Projekte | |
**Ports** (Stand 26.08.2026)
| Port | Belegt durch |
|---|---|
| 22 | SSH |
| 3306 | MariaDB (nur localhost) |
| 3389 | RDP |
| 5000 | vorhandener Dienst (nur IPv6-localhost) |
| 631 | CUPS |
**Nachträglich installiert:** MariaDB 11.8.6, Xvfb, xdotool, ImageMagick, x11-utils
(alle am 26.08.2026 für PolyTrader).
---
## 7. Aufräumen nach dem Test
```bash
# Virtuelles Display beenden (falls noch offen) - NUR das eigene!
pkill -f "Xvfb :<deine-nummer>"
rm -f /tmp/<projekt>_*.png /tmp/<projekt>_gui.log
# Dienst abschalten und entfernen
sudo systemctl disable --now <projekt>
sudo rm -f /etc/systemd/system/<projekt>.service /etc/logrotate.d/<projekt>
sudo systemctl daemon-reload
# Dateien
sudo rm -rf /opt/<projekt> ~/<projekt>-test
sudo userdel <projekt>
# Datenbank (nur wenn nicht mehr gebraucht)
sudo mariadb -e "DROP DATABASE <projekt>_test; DROP USER '<projekt>_test'@'localhost';"
rm -f ~/.<projekt>_test_dbpw
# sudo-Freigabe zurücknehmen
sudo rm -f /etc/sudoers.d/99-testing
```
Danach Abschnitt 6 nachziehen.
---
## 8. Bekannte Einschränkungen
- **Claude Code lässt sich auf dieser VM nicht betreiben.** Es blockiert die Maschine bis zum
Neustart; mehrere Reparaturversuche waren erfolglos, es wird auf ein Update gewartet. Agenten
arbeiten deshalb **über SSH von außen**. (Speichermangel ist **nicht** die Ursache — die
Maschine hat 31 GB, davon 25 GB frei.)
- **Verbindungs-Multiplexing funktioniert nicht mit Windows-OpenSSH** (siehe 2.3).
- **Die Systemzeitzone ist Testgegenstand.** Für realistische Servertests wird sie zeitweise auf
UTC gestellt (`sudo timedatectl set-timezone UTC`). Wer sie ändert, stellt sie danach zurück —
Standard hier ist `Europe/Berlin`.
| §1 Was diese Maschine ist | §1 — unverändert |
| §2 Zugang einrichten | §2 — unverändert |
| §3 Was installiert ist | §3 — unverändert |
| — | **§4 Das Testkit** (neu) |
| §4.1 Datenbanken | §5.1 |
| §4.2 Verzeichnisse | §5.2 |
| §4.3 systemd-Dienste | §5.3 |
| §4.4 Ports | §5.4 |
| §4.5 X-Displays | §5.5 |
| §4.6 Erhöhte Rechte | §5.6 |
| §4.7 GUI ohne Bildschirm | §5.7 |
| **§4.8 Oberflächen selbst begutachten** | **§5.8** |
| §5 Was hier nicht passieren darf | §6 |
| §6 Belegung | §7 |
| **§7 Aufräumen** | **§8** |
| §8 Bekannte Einschränkungen | §9 |
Betroffen sind [BEFUND-Linux-Betrieb-2026-08-26.md](./pruefplaene/BEFUND-Linux-Betrieb-2026-08-26.md)
(§4.8 und §7) und [ROADMAP.md](./ROADMAP.md). Die Verweise wurden bewusst **nicht** umgeschrieben:
Ein Befundbericht ist eine Momentaufnahme und soll lesen wie am Tag seiner Erstellung. Diese
Tabelle löst sie auf.
@@ -1,4 +1,4 @@
# Befundbericht: Erster Linux-Lauf
# Befundbericht: Erster Linux-Lauf
**Datum: 26.08.2026** · Prüfplan: [PRUEFPLAN-Linux-Betrieb.md](./PRUEFPLAN-Linux-Betrieb.md) ·
Roadmap: [A4a](../ROADMAP.md)
@@ -559,7 +559,7 @@ sinnvoll festlegen lassen. Das Verfahren ist reproduzierbar:
# Nachtrag 5: Behebung der offenen Befunde (27.08.2026)
Die Nacharbeit ist unter Windows entstanden und dort gebaut und geprüft
(`dotnet build -c Release`: 0 Fehler / 15 Warnungen wie zuvor; **484 Tests grün**, 8 davon neu;
(`dotnet build -c Release`: 0 Fehler / 15 Warnungen wie zuvor; **486 Tests grün**, 10 davon neu;
`--smoke-ui` durchgängig `[OK]`). Die **Gegenprobe am Bild steht aus** — sie gehört auf die
Linux-VM, nach dem Verfahren aus [TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md) §4.8
mit `testdaten-ui.sql`.
@@ -577,6 +577,7 @@ mit `testdaten-ui.sql`.
| **B-13** · Name unsichtbar | Im Master-Trader-Grid steht **Name** jetzt direkt hinter `#` mit `MinWidth="180"`; die Wallet-Adresse folgt gekürzt (`0x9e2b…3b95`, neuer `ShortAddressConverter`), die vollständige Adresse im Tooltip |
| **B-14** · mehrzeilige Texte | Neuer Feldtyp `MultilineTextSettingsField`; „Beschreibung" und „Begründung" sind am Modell mit `[DataType(DataType.MultilineText)]` ausgezeichnet und erscheinen als sechszeiliges Feld mit Umbruch |
| **B-15** · ein Datensatz legt das Modul lahm | Die Wertkonvertierung läuft über `AccountIdSetJson`: JSON-Array wie bisher, eine reine Zahlenliste (`"1,2"`) wird als Altformat noch verstanden, alles andere ergibt eine **leere** Zuordnung. Der Trader wird also geladen und kopiert auf kein Konto — die sichere Richtung. Die Hydration meldet Anzahl und letzten Rohwert als Warnung |
| **§8** · Logs stempeln UTC, Oberfläche zeigt Ortszeit | **Auf Richards Entscheidung aus T2 vorgezogen.** `LogMessageEventArgs.Timestamp` ist jetzt ein `DateTimeOffset` in der Anzeige-Zeitzone (neu: `AppTimeZone.Now` / `.Today`) statt `DateTime.Now` der Systemuhr. Damit stimmen Zeitstempel, `zzz`-Offset in der JSONL und die Tagesgrenze der Logdateien mit der Oberfläche überein. Mitgezogen: der Log Viewer rechnet nicht mehr doppelt um, Startseite und Viewer wählen die Tagesdatei nach der Anzeige-Zone, und der Supervisor-Tagesbericht läuft zur genannten Stunde in dieser Zone statt in der des Systems. Der Rest von **T2** (Umstellung auf `Microsoft.Extensions.Logging`) bleibt offen |
| **B-12** · Lizenzschlüssel im Klartext | **Ursache gefunden:** `LicenseCli` läuft vor dem Host-Aufbau und rief damit `SecretProtection.Protect` ohne geladenen Master-Key auf — der reicht den Klartext unverändert durch. Die CLI lädt den Master-Key jetzt selbst. Zusätzlich zieht der Start einen noch im Klartext liegenden Schlüssel einmalig verschlüsselt nach (selbstheilende Migration wie bei den DB-Secrets) |
## Nebenbefund aus der Nacharbeit — **alle Dezimal-Einstellungen waren nicht änderbar**
@@ -632,7 +633,106 @@ unverändert für alle Schaltflächen. **Bewusst so eng geschnitten:** Trifft di
| Befund | Grund |
|---|---|
| **B-3** · `--smoke-ui` verlangt eine Datenbank | Eigener Schnitt: Persistenz überspringen oder gegen EF-InMemory bauen. Betrifft fünf DbContexts und hängt daran, ob die CI diesen Modus nutzen soll — siehe A2 |
| **B-4** · `--smoke-ui` braucht einen X-Server | Zwei Wege (`xvfb-run` im Build-Image vs. `Avalonia.Headless` im Code). Gehört zu derselben Entscheidung wie B-3 |
| **§8** · Logs stempeln UTC, Oberfläche zeigt Ortszeit | Gehört zu **T2** (Umstellung auf `Microsoft.Extensions.Logging`). Ein sauberer Fix braucht `DateTimeOffset` statt `DateTime` in `LogMessageEventArgs` — das berührt jede Logzeile der Anwendung und ist kein Nebenbei-Schnitt |
| **B-3** · `--smoke-ui` verlangt eine Datenbank | **Entscheidung Richard, 27.08.2026: vorerst nichts tun.** A2 (CI-Runner) ist pausiert, es gibt keinen Runner — die Prüfung läuft ohnehin von Hand, und auf der Test-VM sind Datenbank und `xvfb` vorhanden. Wieder aufzugreifen, wenn A2 weitergeht |
| **B-4** · `--smoke-ui` braucht einen X-Server | Dieselbe Entscheidung. Für den Handlauf auf der VM genügt ein vorgeschaltetes Xvfb — aber **`xvfb-run -n 99`, nicht `-a`**: `-a` sucht sich selbst ein Display und fängt bei `:99` an, also auf PolyTraders fester Nummer (siehe [TESTUMGEBUNG-Linux-VM.md](../TESTUMGEBUNG-Linux-VM.md), Displaynummern je Projekt) |
| Leerzustände melden nichts | Betrifft rund vierzehn Grids und ist reine Zutat, kein Fehler. Sinnvoll zusammen mit der nächsten Sichtprüfung zu entscheiden |
---
# Nachtrag 6: Gegenprobe am Bild (28.08.2026)
Erster Lauf nach dem neuen Verfahren aus
[`Deploymentcenter/docs/TESTUMGEBUNG.md`](../TESTUMGEBUNG-Linux-VM.md) — Sichtprüfung auf
Display `:99`, mit den Testdaten aus `testdaten-ui.sql`. **Ab hier landen Befunde im Bugtracker
statt in diesem Bericht**; die Nummern in Klammern sind Item-IDs.
**Linux-Build:** 0 Fehler, 15 Warnungen — Zahl für Zahl wie unter Windows. **484 Tests grün.**
`--smoke-ui` unter `xvfb-run -n 99` durchgängig `[OK]`, einschließlich der neuen Prüfung auf
bearbeitbare Einstellungsfelder.
## Im Bild bestätigt
| Befund | Beleg |
|---|---|
| **B-6** Kontrast | Die Zahlen in den KPI-Kacheln stehen im Dunkelmodus jetzt in der aufgehellten Bedeutungsfarbe — CopyTrading grün, ResolutionFarming und Gesamt rot. Der Themenwechsel-Fehler ist weg |
| **B-7** doppelter Modulname | Kachel trägt „CopyTrading" nur noch als Überschrift |
| **B-11** Überschriften | Im ResolutionFarming-Grid stehen „Fee (bps)", „Netto-Edge %", „Outcome" und „Score" vollständig; im Dashboard „Wallet (USDC)", „3T Winrate %", „Overall P/L". Vorher waren dieselben Köpfe abgeschnitten |
| **B-13** Name unsichtbar | Alle fünf Anzeigenamen lesbar (*WeatherWhale*, *PolitiSniper*, *SportsEdge Capital*, *MacroTrend Research*, *CryptoDegen9000*), Wallet gekürzt als `0x9e2b…3b95` |
| **B-14** einzeilige Felder | „Beschreibung" bricht jetzt über drei Zeilen um |
| **B-12** Klartextschlüssel | Beim ersten Start auf der VM im Log: „🔐 Lizenzschlüssel lag im Klartext vor und wurde verschlüsselt nachgezogen." Die selbstheilende Migration wirkt auf der Zielplattform |
| Account-Übersicht | „Demo Testkonto stillgelegt (Demo)" und „CopyTrading, ResolutionFarming" stehen vollständig — beides war zuvor abgeschnitten |
## B-9 · Kalendersymbol — **kein Fehler von PolyTrader** (Item #50)
**Die Zahl ist das heutige Datum.** Am 26.08. stand dort eine „26", am 28.08. eine „28". Avalonia
zeichnet im Knopf des `CalendarDatePicker` die heutige Tageszahl in ein Kalenderblatt — es gibt
dafür eigens die Themenressource `CalendarDatePickerCurrentDayFontSize`. Unter Linux fehlt der
Blatt-Glyph; übrig bleiben die Zahl und ein Punkt darüber.
Zwei Gegenproben, beide ohne Wirkung auf das Bild:
1. Die Formatvorlage der Anwendung per `Button:not(#PART_Button)` vom Knopf ferngehalten.
2. Farbschema auf hell umgeschaltet.
Die am 27.08. auf Verdacht eingebaute Änderung an `App.axaml` ist deshalb **zurückgenommen** —
sie war wirkungslos, und eine Änderung ohne Wirkung und ohne Begründung gehört nicht in den Code.
An ihrer Stelle steht ein Kommentar, damit der Nächste nicht dieselbe Spur verfolgt.
> Zu lernen daraus: Vier Testläufe haben dieselbe Stelle als Artefakt gedeutet. Aufgefallen ist
> es erst, weil an **zwei verschiedenen Tagen** hingesehen wurde. Ein Bildschirmfoto ist eine
> Momentaufnahme — was sich mit dem Datum ändert, verrät sich nur im Vergleich.
## Neuer Fehler durch die eigene Behebung (Item #56) — **behoben**
Die Spaltenbreiten-Umstellung vom 27.08. hat im Master-Trader-Grid etwas kaputtgemacht, das
vorher funktionierte: Von zwölf Spalten blieben sieben brauchbar. Nach „Winrate %" stand eine
Spalte mit abgeschnittenen Werten **ohne Überschrift**, dahinter vier leere Streifen von wenigen
Pixeln — PnL, Copy-PnL, Profit-Faktor, Ø PnL/Trade und Copy-Trades waren weder lesbar noch als
Spalte erkennbar.
**Das war schlimmer als B-11 selbst.** Dort fehlten Überschriften, hier fehlten die Werte.
Ursache: `Name` stand auf `Width="*"` mit `MinWidth`. Zwölf Spalten passen neben dem 460 px
breiten Detailbereich nicht ins Fenster; statt waagerecht zu schieben, verteilt das DataGrid den
Mangel — die Sternspalte behält ihre Mindestbreite, die `Auto`-Spalten am Ende werden zerdrückt.
Behoben durch `Width="Auto"` auch für `Name`. Ohne Sternspalte behält jede Spalte ihre natürliche
Breite, und das Grid lässt sich waagerecht schieben. Im Bild gegengeprüft: „PnL (7T)" zeigt
vollständige Werte, der Rollbalken ist da.
**Regel für alle Grids:** Eine Sternspalte nur dort, wo tatsächlich Platz übrig bleibt. Wo mehr
Spalten als Platz da sind, ist `Auto` plus waagerechtes Schieben das ehrlichere Verhalten — es
versteckt nichts.
## Nebenbei: ein wackliger Testlauf abgestellt
Von sechs Testlaeufen fiel einer um und liess sich danach nicht wieder einfangen. Ursache ist
kein einzelner Test, sondern die Bauart: Mehrere Bausteine halten **prozessweiten** Zustand, den
Tests bewusst umstellen — `AppTimeZone`, `SecretProtection`, die Diagnosezähler von
`AccountIdSetJson`. xUnit führt Testklassen standardmäßig **nebenläufig** aus, also sieht eine
Klasse mitten im eigenen Lauf, was eine andere gerade umgestellt hat.
Neu ist das nicht, aber die Zeitzonen-Umstellung aus §8 hat es verschärft: Seit die Logzeitstempel
der Anzeige-Zeitzone folgen, hängt **jedes** `LogMessageEventArgs` an `AppTimeZone` — während
`AppTimeZoneTests` dieselbe Einstellung nach Auckland und zurück dreht.
Abgestellt durch `[assembly: CollectionBehavior(DisableTestParallelization = true)]`
(`tests/PolyTrader.Tests/AssemblyInfo.cs`); die Zählerprüfungen arbeiten zusätzlich mit der
Differenz statt mit absoluten Werten. Kosten: 3 s → 4–5 s Laufzeit. Danach sechs Läufe in Folge
grün.
## Was jetzt im Bugtracker steht
| Item | Projekt | Inhalt |
|---|---|---|
| **#50** | polytrader | B-9 Kalendersymbol — Diagnose oben, rein kosmetisch |
| **#51** | polytrader | Leere Tabellen sagen nicht, warum sie leer sind |
| **#52** | polytrader | `--smoke-ui` setzt Datenbank und X-Server voraus (B-3/B-4) |
| **#56** | polytrader | Master-Trader-Grid: zerdrückte Spalten — behoben, s.o. |
| **#53** | deploymentcenter | `dc-testkit.sh` hat CRLF und ist auf Linux nicht ausführbar |
| **#54** | deploymentcenter | `dc-testkit doctor` meldet „Bereit." trotz zu altem Server und falschem Token |
| **#55** | deploymentcenter | Fremdmeldung: Laufzeit-Token akzeptiert, kein `triage_external`, kein `reported_from` |
| **#57** | deploymentcenter | `TESTUMGEBUNG.md`: drei Ungenauigkeiten aus dem ersten Durchlauf |
**Damit ist dieser Bericht abgeschlossen.** Was noch offen ist, steht im Bugtracker.