docs(konzept): Entscheide 5-7 — kein Zertifikat, Gitea-Updates, Altlast weg

Die drei offenen Punkte aus KONZEPT-WINDOWS sind entschieden (30.08.2026).

Entscheid 5 — kein Code-Signing-Zertifikat. Die SmartScreen-Warnung wird
hingenommen und in der Anleitung erklaert. Die Folge gehoert dazu und steht
jetzt in 6.8: Ohne Signatur kann electron-updater ein Update nicht auf
Echtheit pruefen, also ist der Transportweg die einzige Absicherung —
Updates nur ueber HTTPS, eine http-Adresse wird abgelehnt.

Entscheid 6 — Updates aus Gitea, auch fuer Externe erreichbar. Rippys
Seite ist einfach: die Adresse steht in der Konfiguration, electron-updater
braucht nur einen statischen HTTPS-Ort. Die Netz-Seite ist es nicht —
Gitea liegt auf 192.168.178.153 im Heimnetz und ist von aussen nicht
erreichbar. Drei Wege sind aufgeschrieben und bewertet (Gitea
veroeffentlichen / oeffentlicher Spiegel / eigene Quelle je Nutzer),
Empfehlung ist der Spiegel. Rippy wird fuer alle drei gebaut, die
Entscheidung kann spaeter fallen ohne Programmaenderung.

Entscheid 7 — der alte Windows-Weg wird entfernt, auch aus main. Dafuer
gibt es einen neuen Abschnitt 11 mit der Arbeitsliste, und die zerfaellt
in DREI Teile statt einem:

  A  die Standalone-App (PyInstaller, Tray, Fenster, Win32-Treiber,
     lokale Queue, Werkzeug-Beschaffung)          -> weg
  B  der Remote-Encode-Worker fuer die Docker-Installation -> BLEIBT
  C  die verstreuten os.name=="nt"-Zweige im Docker-Code -> einzeln pruefen

Dass B bleibt, ist ausdruecklich als Auslegung markiert, nicht als
Anweisung: Der Remote-Worker ist eine Funktion der Docker-Installation,
und Entscheid 2 haelt die unangetastet. Ihn mit abzuraeumen wuerde der VM
eine Faehigkeit nehmen, die niemand gekuendigt hat.

Teil C ist der heikle: pfade.py bleibt (der Remote-Worker braucht
Laufwerkswurzeln und UNC), nativ_nachsehen() ist zu pruefen, und die
Faehigkeiten-Auskunft /betrieb bleibt sinnvoll — nur ihre Windows-Werte
fallen weg.

Zeitpunkt: erst NACH v5 W-6. Solange v5 nicht installierbar ist, ist die
alte Fassung das einzige Windows-Rippy — sie vorher zu loeschen waere eine
Luecke ohne Gegenwert. Der Entscheid nennt die Richtung, kein Datum.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-30 15:52:37 +02:00
co-authored by Claude Opus 5
parent cb811bec28
commit fde3a78e97
+194 -26
View File
@@ -17,7 +17,8 @@
| 45 | Wie ist das Programm aufgebaut, und was passiert, wenn eine Disc reingeht? | | 45 | Wie ist das Programm aufgebaut, und was passiert, wenn eine Disc reingeht? |
| 69 | Features, Oberfläche, Setup, Werkzeuge | | 69 | Features, Oberfläche, Setup, Werkzeuge |
| 10 | Was kommt aus dem alten Rippy mit? | | 10 | Was kommt aus dem alten Rippy mit? |
| 1113 | Etappen, Risiken, was NICHT gebaut wird | | 11 | Was aus `main` entfernt wird |
| 1214 | Etappen, Risiken, was NICHT gebaut wird |
**Was dieses Dokument NICHT tut:** Es erfindet keine Messungen. Alles, was hier **Was dieses Dokument NICHT tut:** Es erfindet keine Messungen. Alles, was hier
als Zahl oder Verhalten steht, ist entweder in § 3 an dieser Maschine gemessen, als Zahl oder Verhalten steht, ist entweder in § 3 an dieser Maschine gemessen,
@@ -69,8 +70,10 @@ bei einem Container, dem man Windows beibringt.
## 2. Die Entscheidungen (Commander, 30.08.2026) ## 2. Die Entscheidungen (Commander, 30.08.2026)
Vier Fragen wurden gestellt, vier sind beantwortet. Sie stehen hier, damit Sieben Entscheide, alle am selben Tag. Die ersten vier legen die Architektur
später nachvollziehbar ist, was Entscheidung war und was Vorschlag. fest, die letzten drei beantworten die Punkte, die das Konzept offengelassen
hatte. Sie stehen hier, damit später nachvollziehbar ist, was Entscheidung war
und was Vorschlag.
### Entscheid 1 — Alles TypeScript/Node ### Entscheid 1 — Alles TypeScript/Node
@@ -120,6 +123,62 @@ v2-Konzepts, nur ohne Container drumherum.
Ein Git-Worktree unter `.claude/worktrees/windows-electron` auf dem Branch Ein Git-Worktree unter `.claude/worktrees/windows-electron` auf dem Branch
`worktree-windows-electron`. `main` bleibt unberührt und jederzeit deploybar. `worktree-windows-electron`. `main` bleibt unberührt und jederzeit deploybar.
### Entscheid 5 — Kein Code-Signing-Zertifikat
*„ist egal, brauchen wir nich"*
Die EXE bleibt unsigniert. Folge: Beim ersten Start eines Downloads zeigt
Windows den SmartScreen-Hinweis („Der Computer wurde geschützt"); über
**Weitere Informationen → Trotzdem ausführen** geht es weiter. Das gehört in
die Anleitung, nicht unter den Teppich.
Eine Folge, die dazugehört und in § 6.8 steht: Ohne Signatur kann
`electron-updater` ein heruntergeladenes Update **nicht** auf Echtheit prüfen.
Die Absicherung liegt damit vollständig beim Transportweg — Updates werden nur
über **HTTPS** geladen, nie über einfaches HTTP.
### Entscheid 6 — Updates aus Gitea, auch für Fremde erreichbar
*„Gerne das Gitea Release, mit Möglichkeit dass auch EXTERNE diese Updates
fahren können"*
Zwei Teile, und der zweite hat eine Bedingung, die Rippy nicht selbst lösen
kann:
1. **Rippys Seite** — die Update-Adresse steht in der Konfiguration, vorbelegt
mit dem Gitea des Commanders. `electron-updater` braucht dafür nur einen
statischen HTTPS-Ort mit zwei Dateien (`latest.yml` und das Setup). Damit
ist Rippy von der Frage unabhängig, *wo* dieser Ort liegt.
2. **Die Netz-Seite** — ⚠️ **Gitea läuft auf `192.168.178.153` im Heimnetz.
Von außen ist das nicht erreichbar.** „Externe können Updates fahren"
verlangt also einen von drei Wegen, und die Wahl gehört dem Commander:
| Weg | Was zu tun ist | Bewertung |
|-----|----------------|-----------|
| **Gitea veröffentlichen** | Reverse-Proxy + DynDNS + TLS-Zertifikat | Ein Dienst im Heimnetz wird öffentlich — die Angriffsfläche wächst. Nur mit Bedacht |
| **Öffentlicher Spiegel** | Der Bau schiebt das Release zusätzlich zu einem öffentlichen Ort (GitHub-Release, Objektspeicher, gemieteter Webspace) | **Empfehlung.** Gitea bleibt privat, nur die fertigen Dateien liegen draußen |
| **Jeder trägt seine eigene Quelle ein** | Nichts — die Konfiguration kann es schon | Für einzelne Nutzer mit eigenem Server. Skaliert nicht |
Rippy wird für **alle drei** gebaut: eine Adresse in der Konfiguration,
sonst nichts. Die Entscheidung kann später fallen, ohne das Programm
anzufassen.
### Entscheid 7 — Der alte Windows-Weg wird entfernt, auch aus `main`
*„Nein — direkt weg, auch aus dem Original Repo. Das neue Standalone Windows
Rippy wird ein komplett neues Produkt und kein Aufbau auf die
Docker-Architektur."*
Die PyInstaller-Fassung bleibt **nicht** parallel installierbar, und ihr Code
verlässt das Repo. Das ist die schärfere Fassung von Entscheid 2: Nicht nur
werden die beiden Produkte nicht verwandt sein — der Zwitter dazwischen wird
abgeräumt.
**Das ist kein Widerspruch zu Entscheid 2.** „Docker bleibt unangetastet" meint
die Docker-*Funktion*; der Windows-Standalone-Zweig ist gerade nicht Docker,
sondern der Fremdkörper darin. Was genau entfernt wird, steht in § 11 — mit
einer Unterscheidung, die beim Aufräumen entscheidend ist.
--- ---
## 3. Was gemessen wurde, bevor entschieden wurde ## 3. Was gemessen wurde, bevor entschieden wurde
@@ -489,13 +548,29 @@ Dazu die Pfad-Regeln aus rc11, als reine Funktionen mit Tests:
### 6.8 Selbst-Update *(neu)* ### 6.8 Selbst-Update *(neu)*
`electron-updater` gegen die Releases im Gitea. Rippy prüft beim Start und `electron-updater` gegen die Releases im Gitea (Entscheid 6). Rippy prüft beim
danach täglich, lädt im Hintergrund und installiert beim nächsten Start — Start und danach täglich, lädt im Hintergrund und installiert beim nächsten
**nie mitten in einem Rip**. Start — **nie mitten in einem Rip**.
Die Quelle steht in der Konfiguration und ist vorbelegt mit dem Gitea des Die Quelle steht in der Konfiguration und ist vorbelegt. Ein nicht erreichbarer
Commanders. Ein nicht erreichbarer Update-Server ist kein Fehler, sondern eine Update-Server ist kein Fehler, sondern eine Zeile im Protokoll.
Zeile im Protokoll.
**Vier Regeln, die zum Entscheid gehören:**
1. **Nur HTTPS.** Ohne Code-Signing (Entscheid 5) kann `electron-updater` ein
heruntergeladenes Update nicht auf Echtheit prüfen — die Absicherung liegt
damit ganz beim Transportweg. Eine `http://`-Update-Adresse wird abgelehnt,
nicht stillschweigend akzeptiert.
2. **Nie während eines Rips.** Weder herunterladen noch installieren. Ein
Neustart mitten in einem 90-Minuten-Rip wäre der teuerste Fehler, den ein
Update-Mechanismus machen kann.
3. **Ein Fehlschlag ist sichtbar, aber nicht laut.** Die Prüfung darf still
scheitern (WLAN weg, Server aus) — aber der Zeitpunkt der letzten
erfolgreichen Prüfung steht im Über-Dialog. Wer nie prüft, weiß sonst nicht,
dass er nie prüft.
4. **Die Version, die läuft, ist ablesbar.** Im Fenster und im Protokollkopf.
Eine Fehlermeldung ohne Versionsnummer ist bei einem sich selbst
aktualisierenden Programm die halbe Miete verloren.
### 6.9 Erst-Einrichtung *(neu gedacht)* ### 6.9 Erst-Einrichtung *(neu gedacht)*
@@ -602,11 +677,15 @@ der Autostart-Eintrag der richtige Weg.
Installationsort aus der Registry eine Wurzel wäre, löschte die Installationsort aus der Registry eine Wurzel wäre, löschte die
Deinstallation das Laufwerk. Nicht beobachtet — aber nicht wiedergutzumachen. Deinstallation das Laufwerk. Nicht beobachtet — aber nicht wiedergutzumachen.
> ⚠️ **SmartScreen.** Eine unsignierte EXE bekommt beim ersten Start eine > **SmartScreen — entschieden (Entscheid 5): kein Zertifikat.** Die unsignierte
> Warnung („Der Computer wurde geschützt"). Ein Code-Signing-Zertifikat kostet > EXE bekommt beim ersten Start eine Warnung („Der Computer wurde geschützt");
> etwa 200400 € im Jahr. Für den Eigengebrauch ist die Warnung hinnehmbar; > über **Weitere Informationen → Trotzdem ausführen** geht es weiter. Das
> das gehört in die Anleitung, nicht unter den Teppich. **Offener Punkt für den > gehört in die Anleitung, nicht unter den Teppich — und die Anleitung sagt
> Commander.** > auch, woran man erkennt, dass die Datei aus der richtigen Quelle stammt
> (Größe und Prüfsumme stehen beim Release).
>
> Die Folge für den Update-Weg steht in § 6.8: Ohne Signatur ist der
> Transportweg die einzige Absicherung, also **nur HTTPS**.
--- ---
@@ -690,7 +769,97 @@ Testfälle besteht wie der alte, hat dieselben Fallen abgedeckt.
--- ---
## 11. Etappen ## 11. Was aus `main` entfernt wird
**Entscheid 7.** Die Arbeit gehört in den `main`-Branch, nicht hierher — dieser
Abschnitt ist die Arbeitsliste dafür, damit sie nicht aus dem Gedächtnis
gemacht wird.
### 11.1 Der Windows-Anteil in `main` sind DREI Dinge, nicht eins
Das ist die Unterscheidung, an der ein unvorsichtiges Aufräumen scheitern
würde:
| | Was es ist | Schicksal |
|---|---|---|
| **A** | **Die Standalone-App** — PyInstaller-Setup, Tray, WebView2-Fenster, Einrichtungs-Assistent, lokale Queue, Werkzeug-Beschaffung, Win32-Treiber | **weg** — sie wird durch v5 ersetzt |
| **B** | **Der Remote-Encode-Worker** — ein Windows-PC als Encoder-Knoten *für die Docker-Installation* (`deploy/worker-windows/`, `/worker-setup/*`, Pfad-Map) | **bleibt** — siehe Kasten |
| **C** | **Windows-Anpassungen im Docker-Code** — die `os.name == "nt"`-Zweige in `main.py`, `betrieb.py`, `ablauf.py`, `rohdaten.py` und die Fähigkeiten-Auskunft im UI | **einzeln prüfen** — der heikelste Teil |
> **Warum B bleibt:** Der Remote-Worker ist kein Standalone-Rippy, sondern eine
> **Funktion der Docker-Installation** — ein zweiter Rechner nimmt der VM das
> Komprimieren ab. Entscheid 2 sagt, dass die Docker-Version unangetastet
> bleibt; ihn mit abzuräumen würde der VM eine Fähigkeit nehmen, die heute
> funktioniert und die niemand gekündigt hat.
>
> Das ist eine **Auslegung** des Entscheids, keine Anweisung des Commanders.
> Wenn der Remote-Worker auch weg soll, ist das ein Satz — aber dann bewusst
> und nicht als Nebenwirkung.
### 11.2 Teil A — die Standalone-App (weg)
```
src/rippy/windows_app.py Installer, Dienst, Deinstallation
src/rippy/fenster.py WebView2-Fenster
src/rippy/setup_fenster.py Einrichtungs-Assistent
src/rippy/einrichtung.py Voraussetzungs-Prüfungen
src/rippy/standalone.py lokale Zustellung statt Celery
src/rippy/drives/windows.py Win32-Laufwerkstreiber
src/rippy/drives/win_ioctl.py die Steuercodes
src/rippy/platform/winlauf.py CREATE_NO_WINDOW, Waisen, Job Object
src/rippy/platform/win_registry.py
src/rippy/platform/verknuepfungen.py
src/rippy/platform/dateiangaben.py
src/rippy/tools/ Werkzeug-Katalog + Beschaffung (Windows-only)
src/rippy/rip/audio_cd.py Audio-CD über Win32
src/rippy/rip/musicbrainz_cd.py DiscID-Rechnung
packaging/windows/ der PyInstaller-Bau
dist/windows/ die gebaute EXE + vendor/
+ die zugehörigen test_*.py
```
Dazu: `src/rippy/queue/lokal.py` und `queue/laeufer.py` (die lokale Queue hat
außerhalb der Standalone-App keinen Aufrufer) und `bus/waechter.py`, soweit er
nur die Windows-Disc-Wache bedient.
**Die Steuercodes und Parser sterben nicht — sie sind bereits nach v5
übernommen** (§ 3.2 hat sie aus Node bestätigt, § 10 listet den Rest). Was
gelöscht wird, ist die Python-Fassung, nicht das Wissen.
### 11.3 Teil C — die verstreuten Zweige (einzeln prüfen)
Hier ist blindes Löschen gefährlich, weil manches auch **ohne** die
Standalone-App gebraucht wird — vom Remote-Worker (Teil B) oder von der
Pfad-Behandlung allgemein.
| Fundort | Prüfen |
|---------|--------|
| `docker/api/main.py``betrieb.windows_laufwerke()`, die Browse-Sonderfälle, `/betrieb`-Fähigkeiten | Die Fähigkeiten-Auskunft bleibt sinnvoll (Docker-AiO vs. verteilt), nur die Windows-Werte fallen weg |
| `src/rippy/betrieb.py` | Ganz raus oder auf Docker-Fälle eindampfen |
| `docker/worker/ablauf.py`, `rohdaten.py` | Die Windows-Pfadzweige raus — aber `nativ_nachsehen()` prüfen: gilt es auch für den Remote-Worker? |
| `docker/api/rohdaten.py`, `mounts.py` | dito |
| `src/rippy/pfade.py` | **Bleibt.** Laufwerkswurzeln und UNC braucht auch der Remote-Worker |
| UI: `useBetrieb`, `WorkerVerwaltung`, `Anleitung`, `Settings` | Nur die Standalone-Texte raus; die Worker-Verwaltung bedient Teil B |
| `src/rippy/test_keine_container_reste.py` | Der Wächter-Test wird gegenstandslos — mit weg |
### 11.4 Wie das gemacht wird
1. **Ein eigener Branch**, nicht direkt auf `main`. Der Umfang ist zu groß für
einen Freihand-Commit.
2. **In der Reihenfolge A → C → (B bleibt).** Erst die eindeutigen Dateien,
dann die verstreuten Zweige — sonst sucht man Aufrufer, die es noch gibt.
3. **Die Ampel nach jedem Schritt.** `AGENTS.md` Regel A gilt unverändert; ein
Aufräumen, das die Tests rot macht, ist nicht fertig, sondern angefangen.
4. **Erst wenn v5 die Etappe W-6 erreicht hat.** Solange v5 nicht installierbar
ist, ist die alte Fassung das einzige Windows-Rippy, das es gibt. Sie zu
löschen, bevor der Ersatz steht, wäre eine Lücke ohne Gegenwert — der
Entscheid nennt kein Datum, nur die Richtung.
5. **Ein SAVEPOINT-Eintrag** dazu, mit der Zahl der entfernten Zeilen und dem
Hinweis, wo das Wissen jetzt liegt.
---
## 12. Etappen
**Grundregel:** Jede Etappe endet mit grüner Ampel und einem Programm, das man **Grundregel:** Jede Etappe endet mit grüner Ampel und einem Programm, das man
starten kann. Kein großer Umbau, nach dem monatelang nichts geht. starten kann. Kein großer Umbau, nach dem monatelang nichts geht.
@@ -712,7 +881,7 @@ Ergänzungen, die ohne die Kette keinen Sinn hätten.
--- ---
## 12. Risiken und offene Punkte ## 13. Risiken und offene Punkte
| Risiko | Bewertung | Behandlung | | Risiko | Bewertung | Behandlung |
|--------|-----------|------------| |--------|-----------|------------|
@@ -720,25 +889,24 @@ Ergänzungen, die ohne die Kette keinen Sinn hätten.
| `node:sqlite` in Electron ungeprüft | mittel × unbekannt | Erster Handgriff in W-0. Rückfallebene `better-sqlite3` | | `node:sqlite` in Electron ungeprüft | mittel × unbekannt | Erster Handgriff in W-0. Rückfallebene `better-sqlite3` |
| Neubau dauert länger als eine Reparatur | sicher | Deshalb Entscheid 2: Die Docker-Version läuft weiter. Es entsteht keine Lücke | | Neubau dauert länger als eine Reparatur | sicher | Deshalb Entscheid 2: Die Docker-Version läuft weiter. Es entsteht keine Lücke |
| Electron-Paket ~150200 MB | sicher, gering | Ein einmaliger Download. Der Gegenwert ist eine Werkzeugkette statt zweier | | Electron-Paket ~150200 MB | sicher, gering | Ein einmaliger Download. Der Gegenwert ist eine Werkzeugkette statt zweier |
| SmartScreen bei unsignierter EXE | mittel | § 8 — Anleitung, oder Zertifikat. **Entscheidung offen** | | SmartScreen bei unsignierter EXE | mittel | Entscheid 5: kein Zertifikat. Anleitung + Prüfsumme beim Release |
| **Update ohne Signaturprüfung** | mittel × Folge von Entscheid 5 | § 6.8 — nur HTTPS, `http://` wird abgelehnt. Der Transportweg ist die einzige Absicherung, deshalb darf er nicht optional sein |
| **Öffentliche Update-Quelle für Externe** | offen × Netz-Frage | Entscheid 6 — Gitea liegt im LAN. Rippy ist für alle drei Wege gebaut (Adresse in der Konfiguration); die Wahl ist eine Infrastruktur-Entscheidung, keine Programmänderung |
| **Aufräumen von `main` reißt Docker mit** | mittel × vermeidbar | § 11 — drei Teile sauber getrennt, Remote-Worker bleibt, Ampel nach jedem Schritt, und erst **nach** v5 W-6 |
| koffi + Electron + npm-Install-Sperre | niedrig | § 3.5 gemessen: koffi lädt mit vorgebauten Binärdateien. In W-0 im Electron-Kontext gegenprüfen | | koffi + Electron + npm-Install-Sperre | niedrig | § 3.5 gemessen: koffi lädt mit vorgebauten Binärdateien. In W-0 im Electron-Kontext gegenprüfen |
| Parallel-Rip vs. MakeMKV-Datenverzeichnis | mittel | § 6.5 — **messen, bevor die Grenze festgeschrieben wird** | | Parallel-Rip vs. MakeMKV-Datenverzeichnis | mittel | § 6.5 — **messen, bevor die Grenze festgeschrieben wird** |
| Ein neu geschriebener Parser bringt neue Fehler | mittel | Die alten Testfälle wandern mit (§ 10). Ein Parser, der sie besteht, kennt dieselben Fallen | | Ein neu geschriebener Parser bringt neue Fehler | mittel | Die alten Testfälle wandern mit (§ 10). Ein Parser, der sie besteht, kennt dieselben Fallen |
| 4K-UHD-Schlüssel | gelöst | Unter Windows holt makemkvcon sie selbst — der strukturelle Vorteil dieser Plattform, gemessen 25.07.2026 | | 4K-UHD-Schlüssel | gelöst | Unter Windows holt makemkvcon sie selbst — der strukturelle Vorteil dieser Plattform, gemessen 25.07.2026 |
### Offene Punkte für den Commander ### Alle drei offenen Punkte sind entschieden (30.08.2026)
1. **Code-Signing-Zertifikat** — ja oder nein? (~200400 €/Jahr, sonst Code-Signing: **nein** (Entscheid 5) · Update-Quelle: **Gitea, auch für
SmartScreen-Warnung beim ersten Start) Externe** (Entscheid 6) · alter Windows-Weg: **wird entfernt** (Entscheid 7).
2. **Update-Quelle** — Gitea-Releases auf `192.168.178.153`, oder ein Ordner Was daraus an Arbeit folgt, steht in § 11.
im Netz?
3. **Der alte Windows-Weg** — bleibt `RippySetup.exe` (PyInstaller) parallel
installierbar, bis v5 W-6 erreicht hat? *(Empfehlung: ja, und v5 bekommt
einen eigenen Installationsordner, damit sich die beiden nicht überschreiben.)*
--- ---
## 13. Was NICHT gebaut wird ## 14. Was NICHT gebaut wird
- **Kein Python.** Auch nicht „nur für den einen Parser". - **Kein Python.** Auch nicht „nur für den einen Parser".
- **Kein HTTP-Server, kein Port, kein localhost.** Fenster und Kern reden über - **Kein HTTP-Server, kein Port, kein localhost.** Fenster und Kern reden über