docs(konzept): Zweite Fassung — geprueft, nachgemessen, drei Entscheide

- Faktenfehler korrigiert: Gitea ist oeffentlich per HTTPS erreichbar
  (gemessen, § 3.6) — Updates kommen direkt daraus, Drei-Wege-Tabelle weg
- node:sqlite in Electron 44 im utilityProcess bewiesen (§ 3.4,
  beweise/sqlite-main.js + sqlite-kern.js) — better-sqlite3 nicht noetig
- Disc-Wache umgedreht: 3-Sekunden-Takt ist Plan A, WM_DEVICECHANGE
  spaetere Verfeinerung (§ 5)
- Entscheid 7 verschaerft: main-Aufraeumen sofort, nicht erst nach W-6
- Entscheid 9 neu: Zielgruppe Bekannte mit Link, Lizenztexte liegen bei
- MakeMKV-Lage tagesaktuell bestaetigt (Key bis Ende September 2026,
  Kaufseite defekt = Dauerzustand seit Sommer 2025)
- Electron-Pflege-Regel (§ 6.8), npm-11-Sperre trifft auch Electron
  selbst (§ 3.5), Release = drei Dateien, 4K-Schluesselkette in § 10,
  Risikotabelle aktualisiert

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-08-30 16:20:51 +02:00
co-authored by Claude Fable 5
parent e514e4070b
commit c44bfa6daa
4 changed files with 1187 additions and 998 deletions
+256 -121
View File
@@ -3,7 +3,19 @@
> **Rippy v5.** Ein eigenständiges Windows-Programm, gebaut mit Electron und
> TypeScript. Grüne Wiese: kein Docker-Code, kein Python, keine Container-Reste.
>
> Stand: 30.08.2026 · Branch `worktree-windows-electron`
> Stand: 30.08.2026, **zweite Fassung** · Branch `worktree-windows-electron`
**Was die zweite Fassung vom selben Tag unterscheidet:** Das Konzept wurde
geprüft, tagesaktuell gegenrecherchiert und nachgemessen. Vier Dinge haben
sich geändert: (1) Ein Faktenfehler ist korrigiert — das Gitea des Commanders
ist entgegen der ersten Fassung **öffentlich erreichbar**, die Update-Frage
löst sich damit fast von selbst (§ 3.6, Entscheid 6). (2) Die letzte
technische Unbekannte ist gemessen — `node:sqlite` funktioniert in Electron 44,
im echten Einsatzkontext (§ 3.4). (3) Die Disc-Erkennung ist vom Kopf auf die
Füße gestellt — der Prüf-Takt ist Plan A, das Windows-Ereignis die spätere
Verfeinerung (§ 5). (4) Drei Entscheide des Commanders sind eingearbeitet:
Update-Quelle, Zielgruppe, und der Zeitpunkt des Aufräumens (Entscheide 6, 7
und 9).
---
@@ -22,10 +34,13 @@
**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,
im alten Rippy belegt (`SAVEPOINT.md`, `AGENTS.md`) oder ausdrücklich als
**Annahme** markiert. Die Trennung ist wichtig, weil dieses Projekt schon
mehrfach teuer dafür bezahlt hat, dass jemand eine plausible Erklärung für eine
gemessene gehalten hat.
im alten Rippy belegt (`SAVEPOINT.md`, `AGENTS.md`), am 30.08.2026 gegen das
Netz geprüft oder ausdrücklich als **Annahme** markiert. Die Trennung ist
wichtig, weil dieses Projekt schon mehrfach teuer dafür bezahlt hat, dass
jemand eine plausible Erklärung für eine gemessene gehalten hat. Die erste
Fassung dieses Konzepts hat es selbst vorgemacht: Sie behauptete, Gitea sei
von außen nicht erreichbar — eine Messung von dreißig Sekunden zeigte das
Gegenteil (§ 3.6).
---
@@ -70,10 +85,9 @@ bei einem Container, dem man Windows beibringt.
## 2. Die Entscheidungen (Commander, 30.08.2026)
Acht Entscheide, alle am selben Tag. Die ersten vier legen die Architektur
fest, die naechsten drei beantworten die Punkte, die das Konzept offengelassen
hatte, und der achte steht bei der Sache, zu der er gehoert (Paragraph 11.1). Sie stehen hier, damit später nachvollziehbar ist, was Entscheidung war
und was Vorschlag.
Neun Entscheide, alle am selben Tag — die Entscheide 6, 7 und 9 in ihrer
heutigen Form aus der Prüfung der ersten Fassung. Sie stehen hier, damit
später nachvollziehbar ist, was Entscheidung war und was Vorschlag.
### Entscheid 1 — Alles TypeScript/Node
@@ -127,58 +141,99 @@ Ein Git-Worktree unter `.claude/worktrees/windows-electron` auf dem Branch
*„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.
Die EXE bleibt unsigniert. Zwei Folgen, beide bewusst getragen:
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.
1. **SmartScreen.** Beim ersten Start eines Downloads zeigt Windows den
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 — samt der Angabe, woran man die echte Datei erkennt
(Größe und Prüfsumme stehen beim Release).
2. **Updates ohne Echtheitsprüfung.** Ohne Signatur kann `electron-updater`
ein heruntergeladenes Update nicht auf Echtheit prüfen. Die Absicherung
liegt damit vollständig beim Transportweg — deshalb die HTTPS-Pflicht in
§ 6.8, Regel 1.
### Entscheid 6 — Updates aus Gitea, auch für Fremde erreichbar
### Entscheid 6 — Updates aus dem öffentlichen Gitea
*„Gerne das Gitea Release, mit Möglichkeit dass auch EXTERNE diese Updates
fahren können"*
fahren können"* — und in der zweiten Fassung konkretisiert: **das öffentliche
Gitea direkt, kein Spiegel.**
Zwei Teile, und der zweite hat eine Bedingung, die Rippy nicht selbst lösen
kann:
Die erste Fassung hielt das für ein Infrastruktur-Problem („Gitea ist von
außen nicht erreichbar") und entwarf drei Auswege. Die Messung in § 3.6 hat
das erledigt: **Gitea ist längst öffentlich erreichbar**
`https://git.tobisniceshomelab.ddnsfree.com`, mit gültigem TLS-Zertifikat,
Lesen ohne Anmeldung. Die HTTPS-Pflicht aus § 6.8 ist damit erfüllbar, und
zwar für den Commander **und** für Externe, ohne dass irgendetwas neu
aufgebaut wird.
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:
Was bleibt:
| 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 |
- Die Update-Adresse steht in der Konfiguration, vorbelegt mit den Releases
dieses Gitea. Wer einen eigenen Server hat, trägt seine eigene Adresse ein —
`electron-updater` braucht nur einen statischen HTTPS-Ort.
- Jedes Release besteht aus **drei Dateien**, nicht zwei: `latest.yml`
(die Update-Auskunft), das Setup und die `.blockmap` (macht aus einem
Voll-Download einen Differenz-Download).
- ⚠️ **Ein Handgriff für Etappe W-6:** Gitea-Release-Downloads hängen an
ihrem Tag (`/releases/download/v5.0.1/...`) — `electron-updater` braucht
für `latest.yml` aber eine **feste** Adresse. Ob Gitea 1.27 das
GitHub-Muster `releases/latest/download/...` bedient, ist ungeprüft (2024
war es dort noch ein offener Wunsch). Falls nein, ist die Rückfallebene
simpel: ein festes Update-Tag, dessen drei Dateien der Bau bei jedem
Release ersetzt. Beides ist eine Bau-Einstellung, keine Programmänderung.
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`
### Entscheid 7 — Der alte Windows-Weg wird entfernt, sofort, 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.
verlässt das Repo. Die erste Fassung hatte das Aufräumen auf „erst wenn v5
installierbar ist" gelegt; der Commander hat bei der Prüfung der zweiten
Fassung anders entschieden: **sofort, nicht erst nach Etappe W-6.**
Was das bedeutet, gehört ehrlich hingeschrieben: Zwischen dem Aufräumen und
W-6 liefert das Repo **kein installierbares Windows-Rippy**. Die auf dem
Commander-PC installierte rc11-Fassung läuft lokal weiter, bekommt aber keine
Reparaturen mehr; wer in der Zwischenzeit rippen will, nutzt sie oder die
Docker-Version. Das ist der Preis für ein Repo ohne Zwitter — und er ist
bewusst bezahlt.
**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.
### Entscheid 8 — Der Remote-Worker bleibt bei Docker
*„Das soll NICHT Teil des neuen Standalone-Produktes sein, da dieser NUR für
die Docker-Variante verwendet wird."*
Der „Rippy Worker" auf einem Hilfsrechner ist eine Funktion der
Docker-Installation, kein Standalone-Rippy. Er wird weder abgeräumt noch nach
v5 übernommen. Warum das so ist und was genau er tut, steht in § 11.1 — dort,
wo die Unterscheidung gebraucht wird.
### Entscheid 9 — Zielgruppe: Bekannte mit Link
Neu in der zweiten Fassung: Rippy v5 wird **kein öffentliches Produkt**. Der
Commander gibt die Download-Adresse gezielt weiter — Familie, Freunde. Keine
öffentliche Ankündigung, kein Support-Anspruch Fremder.
Konsequenzen:
- Anleitung, SmartScreen-Erklärung und Prüfsummen bleiben **schlank** — sie
müssen einen wohlwollenden Bekannten durchbringen, kein anonymes Publikum.
- Die **Lizenztexte gehören trotzdem dazu.** Weitergabe an Bekannte ist
Weitergabe: HandBrake (GPL-2) und FLAC (BSD-artig) verlangen Lizenztext und
Quellverweis im Paket (§ 9). Das ist keine Formalie für später, sondern
Bestandteil von Etappe W-6.
- Das Repo bleibt lesbar wie bisher; beworben wird nichts. Sollte v5 eines
Tages doch öffentlich werden, ändert sich am Programm nichts — nur an
Anleitung und Sorgfaltstiefe.
---
## 3. Was gemessen wurde, bevor entschieden wurde
@@ -189,7 +244,8 @@ Konzept an einer Frage, die vorher niemand geprüft hat:
> **Kann Node überhaupt alles, was Rippy am Laufwerk braucht?**
Wäre die Antwort nein, wäre das Konzept wertlos. Also gemessen — am
30.08.2026, auf diesem Rechner, am echten Laufwerk.
30.08.2026, auf diesem Rechner, am echten Laufwerk. Die Skripte liegen in
`beweise/` und sind dort nachstellbar dokumentiert.
### 3.1 Die Werkzeuglage
@@ -201,6 +257,11 @@ WebView2 151.0.4129.107
Laufwerk G: HL-DT-ST BD-RE BU40N USB Device (Medium eingelegt)
```
Zur Einordnung, am 30.08.2026 gegen das Netz geprüft: Electron 44 ist die
aktuelle stabile Linie, koffi 3.1.6 die aktuelle Version, Node 24 ist LTS.
Das Konzept baut also nicht auf Auslaufendem auf — was Electron-Versionen
betrifft, gilt aber die Pflege-Regel in § 6.8.
### 3.2 Win32 aus Node — die Laufwerks-Steuerung
`koffi` 3.1.6 installiert, dieselben Steuercodes wie in
@@ -246,23 +307,27 @@ taskkill /F /PID 29488 -> ERFOLGREICH
danach: Eltern lebt: False Kind lebt: False
```
### 3.4 Datenbank ohne native Abhängigkeit
```
node:sqlite eingebaut -> geht
```
### 3.4 Datenbank ohne native Abhängigkeit — in Electron gemessen
Node 24 bringt SQLite mit (`node:sqlite`, `DatabaseSync`). Keine
`better-sqlite3`-Kompilierung, kein `node-gyp`, kein Visual-Studio-Build in der
Bau-Kette.
> ⚠️ **Ungeprüft:** Electron kompiliert sein Node mit eigenen Flags. Ob
> `node:sqlite` in Electron 44 vorhanden ist, ist an *dieser* Stelle **nicht**
> gemessen — nur in Node 24.19.0 selbst. Das ist der erste Handgriff in
> Etappe W-0. Rückfallebene: `better-sqlite3` (bewährt, aber nativ und damit
> eine Kompilierung in der Bau-Kette).
Die erste Fassung musste hier eine Warnung setzen: Electron kompiliert sein
Node mit eigenen Flags, und ob `node:sqlite` dort vorhanden ist, war nur für
Node pur gemessen. **Das ist erledigt — am 30.08.2026 in Electron 44.0.0
gemessen, und zwar im `utilityProcess`**, also exakt dem Kontext, in dem
`kern/speicher/db.ts` laufen wird (§ 4.1):
### 3.5 Ein Nebenbefund für die Bau-Kette
```
KERN-ANTWORT: {"ok":true,"wert":"geht","node":"24.18.1"}
Kern beendet mit 0
```
Anlegen, Schreiben, Lesen — alles grün. Die Rückfallebene `better-sqlite3`
wird nicht gebraucht. Skripte: `beweise/sqlite-main.js` + `sqlite-kern.js`.
### 3.5 Ein Nebenbefund für die Bau-Kette — zweimal bestätigt
`npm` 11 blockiert Install-Skripte fremder Pakete standardmäßig:
@@ -270,9 +335,33 @@ Bau-Kette.
npm warn allow-scripts koffi@3.1.6 (install: node ./cnoke.cjs -P . --prebuild --release)
```
`koffi` lädt trotzdem — es bringt vorgebaute Binärdateien mit. Aber die
Warnung gehört in die Bau-Anleitung, sonst sucht jemand eines Tages an der
falschen Stelle.
`koffi` lädt trotzdem — es bringt vorgebaute Binärdateien mit. **Electron
selbst trifft die Sperre härter:** Sein Install-Skript lädt die eigentliche
Programmdatei herunter; wird es geblockt, liegt nach `npm install` ein Paket
**ohne `dist/electron.exe`** da, und nichts startet. Bei der sqlite-Messung
(§ 3.4) selbst hineingelaufen; `node node_modules/electron/install.js` holt
die Binary nach. Beides gehört in die Bau-Anleitung, sonst sucht jemand eines
Tages an der falschen Stelle.
### 3.6 Die Update-Quelle — gemessen statt vermutet
Die erste Fassung behauptete: *„Gitea läuft auf `192.168.178.153` im Heimnetz.
Von außen ist das nicht erreichbar."* Am 30.08.2026 von außerhalb des
Heimnetzes gemessen:
```
https://git.tobisniceshomelab.ddnsfree.com/Hitonabi/rippy
-> lädt anonym, ohne Anmeldung, über den Reverse-Proxy des Commanders
-> TLS-Zertifikat gültig
-> Gitea 1.27.2 (/api/v1/version)
-> bisher 0 Releases, 0 Tags — der Release-Weg ist frei
```
Die interne Adresse `192.168.178.153:3000` existiert daneben weiter; für
Updates zählt die öffentliche. Damit ist Entscheid 6 keine Infrastruktur-Frage
mehr, sondern eine Bau-Einstellung. Offen bleibt nur die
Fest-Adresse-Feinheit für `latest.yml` (Entscheid 6, ⚠️-Punkt) — die wird in
W-6 am ersten echten Release gemessen.
---
@@ -310,7 +399,8 @@ falschen Stelle.
**Warum `utilityProcess` und nicht `child_process.fork`:** Electrons eigene
Empfehlung. `utilityProcess` kann einen `MessagePort` direkt zum Renderer
aufbauen — der Fortschritt eines Rips geht damit ohne Umweg über den
Main-Prozess ins Fenster.
Main-Prozess ins Fenster. Und § 3.4 hat gezeigt: `node:sqlite` steht genau
dort zur Verfügung.
**Was es NICHT gibt:** keinen HTTP-Server, keinen Port, kein `localhost:7788`,
keine REST-API, kein SSE. Fenster und Kern reden über Electrons IPC. Ein
@@ -335,7 +425,7 @@ rippy-windows/
│ ├── kern/ utilityProcess — die Arbeit
│ │ ├── laufwerk/
│ │ │ ├── win32.ts DER EINZIGE ORT MIT koffi
│ │ │ ├── wache.ts Einwurf/Auswurf erkennen
│ │ │ ├── wache.ts Einwurf/Auswurf erkennen (§ 5, Schritt 1)
│ │ │ └── disc.ts Typ, Label, Größe, TOC
│ │ ├── metadaten/
│ │ │ ├── tmdb.ts tvdb.ts omdb.ts musicbrainz.ts
@@ -360,9 +450,10 @@ rippy-windows/
│ │ ├── werkzeuge/
│ │ │ ├── katalog.ts wo liegt makemkvcon/HandBrakeCLI/flac
│ │ │ ├── beschaffen.ts holen, prüfen, einrichten
│ │ │ ├── schluessel.ts 4K-Schlüsselkette, Beta-Key samt Ablaufdatum (§ 9.1)
│ │ │ └── leine.ts Job Object (§ 3.3)
│ │ └── speicher/
│ │ ├── db.ts SQLite
│ │ ├── db.ts SQLite (node:sqlite — § 3.4 gemessen)
│ │ ├── einstellungen.ts EINE Quelle (§ 6.7)
│ │ └── bibliothek.ts
│ │
@@ -417,8 +508,8 @@ Der rote Faden des Commanders: **so viel Arbeit abnehmen wie möglich.**
```
1. Disc rein
│ WM_DEVICECHANGE / DBT_DEVICEARRIVAL (Ereignis, kein Poll)
Rückfallebene: 3-Sekunden-Takt, falls die Nachricht ausbleibt
│ Wache im 3-Sekunden-Takt (IOCTL_STORAGE_CHECK_VERIFY2 — § 3.2)
Verfeinerung später: WM_DEVICECHANGE-Ereignis (siehe unten)
2. Was ist das?
│ Größe (33,76 GB → Blu-ray) · Audio-TOC? · Dateisystem lesbar?
@@ -442,8 +533,23 @@ Der rote Faden des Commanders: **so viel Arbeit abnehmen wie möglich.**
8. Melden Medienserver anstoßen · Benachrichtigung · Auswerfen
9. Merken Bibliothek fortschreiben — beim nächsten Mal erkannt
```
**Warum der Takt Plan A ist und das Ereignis nicht.** Die erste Fassung
versprach „Ereignis, kein Poll" — die Prüfung hat die Reihenfolge umgedreht.
`WM_DEVICECHANGE` ist eine **Fenster**-Nachricht: Sie wird nur an Fenster mit
Nachrichtenschleife zugestellt, und der Kern hat keines. Beide Auswege sind
machbar, aber krumm — entweder fängt der Main-Prozess die Nachricht am
Fenster ab und muss dann die Frage „welches Laufwerk?" aus einer
Zeiger-Struktur klauben, oder der Kern baut sich per koffi ein unsichtbares
Nachrichten-Fenster samt eigener Schleife. Der 3-Sekunden-Takt dagegen ist
eine Zeile (`IOCTL_STORAGE_CHECK_VERIFY2`, in § 3.2 gemessen, praktisch
kostenlos), und bei einem Vorgang, der 3090 Minuten dauert, sind drei
Sekunden Erkennungsverzögerung bedeutungslos. Also: **Takt zuerst, Ereignis
als spätere Verfeinerung** — und wenn das Ereignis kommt, bleibt der Takt als
Rückfallebene bestehen, falls die Nachricht ausbleibt.
**Was an Schritt 3 neu ist.** Heute nimmt Rippy im Wesentlichen das Disc-Label
und die längste Laufzeit. Das reicht bei „PIRATES_OF_THE_CARIBBEAN", aber nicht
bei „LOGICAL_VOLUME_ID" — und dann fragt Rippy, obwohl die Antwort auf der
@@ -548,19 +654,22 @@ Dazu die Pfad-Regeln aus rc11, als reine Funktionen mit Tests:
### 6.8 Selbst-Update *(neu)*
`electron-updater` gegen die Releases im Gitea (Entscheid 6). Rippy prüft beim
Start und danach täglich, lädt im Hintergrund und installiert beim nächsten
Start — **nie mitten in einem Rip**.
`electron-updater` gegen die Releases im öffentlichen Gitea (Entscheid 6).
Rippy prüft beim Start und danach täglich, lädt im Hintergrund und installiert
beim nächsten Start — **nie mitten in einem Rip**.
Die Quelle steht in der Konfiguration und ist vorbelegt. Ein nicht erreichbarer
Update-Server ist kein Fehler, sondern eine Zeile im Protokoll.
Update-Server ist kein Fehler, sondern eine Zeile im Protokoll — das gilt
ausdrücklich auch, wenn das Heimnetz des Commanders gerade nicht antwortet.
**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.
nicht stillschweigend akzeptiert. (Die Prüfsumme aus `latest.yml` sichert
nur die Übertragung — sie kommt über denselben Kanal wie die Datei und ist
deshalb kein Ersatz für den sicheren Kanal selbst.)
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.
@@ -572,6 +681,14 @@ Update-Server ist kein Fehler, sondern eine Zeile im Protokoll.
Eine Fehlermeldung ohne Versionsnummer ist bei einem sich selbst
aktualisierenden Programm die halbe Miete verloren.
**Und eine Pflege-Regel, die das Selbst-Update erst wertvoll macht:**
Electron bringt etwa alle acht Wochen eine neue Hauptversion und pflegt nur
die letzten drei — wer stehen bleibt, sitzt nach rund einem halben Jahr auf
einem Chromium mit bekannten Sicherheitslücken. Deshalb: **Bei jedem
Rippy-Release wird geprüft, ob ein Electron-Sprung ansteht.** Das Verteilen
kostet dank Selbst-Update nichts; das Nicht-Verteilen kostet irgendwann
Vertrauen.
### 6.9 Erst-Einrichtung *(neu gedacht)*
Der Befund des Commanders zur heutigen Fassung: *„Dann hätte ich beim Setup
@@ -658,6 +775,12 @@ Banner sagt, dass gerade nichts Neues kommt.
| Update | `electron-updater`, NSIS-Ziel (§ 6.8) |
| Deinstallation | Über die Windows-Programmliste, räumt **wirklich** auf |
Zu Windows 10, tagesaktuell eingeordnet: Die Verbraucher-Sicherheitsupdates
(ESU) enden im Oktober 2026, die Chromium-Familie läuft auf Windows 10 aber
erklärtermaßen weiter (Edge/WebView2 bis mindestens Oktober 2028). Electron 44
läuft dort. Für Rippy heißt das: bauen ja, und ein Satz in der Anleitung, dass
Windows 10 selbst ausläuft — mehr nicht.
**Warum kein Windows-Dienst:** Ein Dienst startet vor der Anmeldung — klingt
besser, kostet aber bei jeder Installation und jedem Update eine
Administrator-Abfrage, und er kann kein Tray-Symbol zeigen (keine
@@ -677,15 +800,9 @@ der Autostart-Eintrag der richtige Weg.
Installationsort aus der Registry eine Wurzel wäre, löschte die
Deinstallation das Laufwerk. Nicht beobachtet — aber nicht wiedergutzumachen.
> **SmartScreen — entschieden (Entscheid 5): kein Zertifikat.** Die unsignierte
> EXE bekommt beim ersten Start eine Warnung („Der Computer wurde geschützt");
> über **Weitere Informationen → Trotzdem ausführen** geht es weiter. Das
> gehört in die Anleitung, nicht unter den Teppich — und die Anleitung sagt
> 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**.
Zum SmartScreen-Hinweis beim ersten Start und zur Update-Folge der fehlenden
Signatur: beides steht bei Entscheid 5 — die Anleitung erklärt den Weg, das
Release nennt Größe und Prüfsumme, und Updates laufen nur über HTTPS (§ 6.8).
---
@@ -702,6 +819,10 @@ Bequemlichkeit.
| **FLAC** | **mitgeliefert** (~2 MB) | Xiph-Lizenz (BSD-artig), Weitergabe erlaubt. ⚠️ `flac.exe` braucht `libFLAC.dll` daneben — mit nur der EXE endet jeder Aufruf ohne eine Zeile Ausgabe. |
| **MakeMKV** | **beim Einrichten geholt** | Proprietär — die Lizenz erlaubt Dritten keine Weitergabe. Rippy lädt die offizielle Datei vom Hersteller und startet dessen Installer. |
Die Lizenztexte und Quellverweise für HandBrake und FLAC liegen dem Setup bei
— wegen Entscheid 9 wird die EXE weitergegeben, und damit ist das Pflicht,
nicht Kür.
**Die Bezugskette für MakeMKV** (aus dem 28.08.-Entscheid, unverändert):
eigene Quelle → Hersteller-Seite → Hersteller-Forum → Internet Archive. Mit
zwei Feinheiten, beide gemessen: **Die höchste Versionsnummer gewinnt, nicht
@@ -718,18 +839,23 @@ Download, eine falsche Fassung.
### 9.1 Der Beta-Key — ein Termin, kein Detail
> **MakeMKVs freier Beta-Key ist bis Ende September 2026 gültig. Die Kaufseite
> für die Dauerlizenz ist seit Mai 2026 defekt.**
> für die Dauerlizenz ist defekt — der Hersteller verweist selbst auf den
> Beta-Key.** *(Am 30.08.2026 gegen Forum und Fachpresse geprüft.)*
Das trifft Rippy in etwa vier Wochen, und ohne gültigen Key geht **keine
Blu-ray und keine 4K-Disc** mehr auf (DVDs laufen weiter).
Rippy v5 geht damit so um:
Zur Einordnung, die in der ersten Fassung fehlte: Das ist **kein frischer
Unfall, sondern ein Dauerzustand seit Sommer 2025** — das Kaufsystem fällt
seither immer wieder aus, und der Beta-Key wurde bisher stets kurz vor Ablauf
verlängert (zuletzt Anfang August 2026, gültig bis Ende September). Rippy
plant also nicht für eine einmalige Panne, sondern für einen Rhythmus. Das
Restrisiko — der Hersteller verschwindet ganz — kann kein Programm der Welt
auffangen; was ein Programm auffangen kann, ist das Überraschtwerden:
1. **Der Key wird automatisch geholt** (wie heute) — aus dem Forum-Thread, in
dem der Hersteller ihn veröffentlicht.
2. **Rippy zeigt das Ablaufdatum im Dashboard** und warnt **sieben Tage
vorher** — statt dass ein Rip mitten in der Nacht scheitert und niemand
weiß, warum.
weiß, warum. Ohne gültigen Key geht keine Blu-ray und keine 4K-Disc mehr
auf; DVDs laufen weiter.
3. **Ein abgelaufener Key ist eine klare Meldung**, kein rätselhafter
MakeMKV-Fehlercode.
4. **Ein eingetragener Dauerlizenz-Schlüssel schlägt alles.** Wer eine Lizenz
@@ -757,6 +883,7 @@ Arbeitsliste für den Neubau.
| `prescan.py`, `clients/*` | TMDb/TVDb/OMDb/MusicBrainz/Jikan-Abfragen, Zwischenspeicher, Confidence | `metadaten/` |
| `pfade.py` | Laufwerkswurzeln, UNC, `naechster_vorhandener` **ohne Endlosschleife** | `speicher/pfade.ts` |
| `musicbrainz_cd.py`, `audio_cd.py` | DiscID-Rechnung (mit/ohne 150 Frames), 2048-vs-2352-Falle | `rip/audiocd.ts` |
| `makemkv_daten.py` | Die 4K-Schlüsselkette: Beta-Key-Abruf aus dem Forum-Thread, Schlüsselspeicher (`_private_data.tar`), KEYDB als Notnagel — samt der dort dokumentierten Fehldiagnosen | `werkzeuge/schluessel.ts` |
| `presets.py`, `eta.py`, `phasen.py` | Preset-Zuordnung je Disc-Typ, Restzeit, Phasenmodell | `komprimieren/`, `ablauf/` |
| `beschaffen.py`, `katalog.py` | Suchreihenfolge für Werkzeuge, Registry-Auswertung, Ausweichquellen | `werkzeuge/` |
| `AGENTS.md` | Die sechs Regeln aus § 4.3 | Wächter-Tests |
@@ -771,9 +898,9 @@ Testfälle besteht wie der alte, hat dieselben Fallen abgedeckt.
## 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.
**Entscheid 7 — und zwar sofort.** 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
@@ -805,7 +932,10 @@ Film komprimieren und ist selbst zu langsam, schickt sie die Arbeit dorthin.
Ergebnis ◄───────────────────── schickt zurück
```
B läuft nur *zufällig* auf Windows — es gehört zur Docker-Welt.
B läuft nur *zufällig* auf Windows — es gehört zur Docker-Welt. **Entscheid 8:
B bleibt bei Docker** — es wird weder abgeräumt (es ist Docker, und Docker
bleibt unangetastet) noch nach v5 übernommen (v5 ist Einzelplatz, Entscheid 3
— es gibt dort keinen zweiten Knoten, dem man etwas schicken könnte).
**C — Notizzettel im Docker-Code.** Keine eigenen Dateien, sondern verstreute
Stellen *mitten in* Dateien, die Docker jeden Tag benutzt, wo jemand schrieb:
@@ -832,17 +962,6 @@ geschrieben werden muss (§ 1). Der Handlanger läuft ja auf Windows.
| **B** | **Der Remote-Encode-Worker**`deploy/worker-windows/`, `/worker-setup/*`, Pfad-Map | **bleibt** |
| **C** | **Windows-Zweige im Docker-Code** — die `os.name == "nt"`-Stellen in `main.py`, `betrieb.py`, `ablauf.py`, `rohdaten.py`, dazu die Fähigkeiten-Auskunft im UI | **einzeln prüfen** |
> **Entscheid 8 (30.08.2026) — B bleibt bei Docker und kommt nicht nach v5.**
>
> Commander: *„Das soll NICHT Teil des neuen Standalone-Produktes sein, da
> dieser NUR für die Docker-Variante verwendet wird."*
>
> Damit ist bestätigt, was zuvor nur Auslegung war: Der Remote-Worker ist kein
> Standalone-Rippy, sondern eine **Funktion der Docker-Installation**. Er wird
> weder abgeräumt (er ist Docker, und Docker bleibt unangetastet) noch nach v5
> übernommen (v5 ist Einzelplatz, Entscheid 3 — es gibt dort keinen zweiten
> Knoten, dem man etwas schicken könnte).
### 11.2 Teil A — die Standalone-App (weg)
```
@@ -871,7 +990,10 @@ 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.
gelöscht wird, ist die Python-Fassung, nicht das Wissen. Wichtig fürs
Löschen von `makemkv_daten.py`-Verwandten: Die Schlüsselketten-Erkenntnisse
(§ 10) VOR dem Löschen in v5-Notizen sichern, falls W-7 noch nicht begonnen
hat — das Wissen darf nicht nur im Git-Verlauf liegen.
### 11.3 Teil C — die verstreuten Zweige (einzeln prüfen)
@@ -891,16 +1013,17 @@ Pfad-Behandlung allgemein.
### 11.4 Wie das gemacht wird
1. **Ein eigener Branch**, nicht direkt auf `main`. Der Umfang ist zu groß für
1. **Jetzt, nicht erst wenn v5 steht.** Commander-Entscheid vom 30.08.2026
(zweite Fassung): Das Aufräumen wartet **nicht** auf Etappe W-6. Die
Konsequenz steht bei Entscheid 7 — zwischen Aufräumen und W-6 liefert das
Repo kein installierbares Windows-Rippy; die installierte rc11-Fassung
läuft lokal weiter, bekommt aber keine Reparaturen mehr.
2. **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,
3. **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
4. **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.
@@ -911,16 +1034,19 @@ Pfad-Behandlung allgemein.
**Grundregel:** Jede Etappe endet mit grüner Ampel und einem Programm, das man
starten kann. Kein großer Umbau, nach dem monatelang nichts geht.
**Parallel dazu, unabhängig von den Etappen:** das Aufräumen von `main`
(§ 11.4) — es startet sofort und braucht auf nichts hiervon zu warten.
| # | Titel | Inhalt | Fertig, wenn |
|---|-------|--------|--------------|
| **W-0** | **Gerüst** | Electron 44 + TypeScript + Vite + Vitest, drei Prozesse, IPC, `node:sqlite` in Electron **prüfen** (§ 3.4), Prozess-Leine, CI-Ampel | Ein Fenster geht auf, der Kern läuft, ein Testlauf ist grün |
| **W-1** | **Laufwerk** | `laufwerk/win32.ts` aus dem § 3.2-Beweis, Wache über `WM_DEVICECHANGE`, Disc-Typ, Verriegeln, Auswerfen mit Nachsehen | Disc rein → Rippy sagt korrekt, was es ist. Auswerfen wirkt (nachgemessen, nicht geglaubt) |
| **W-0** | **Gerüst** | Electron 44 + TypeScript + Vite + Vitest, drei Prozesse, IPC, `node:sqlite` anbinden (§ 3.4 — bereits bewiesen), Prozess-Leine, CI-Ampel, npm-Skript-Sperre in der Bau-Anleitung (§ 3.5) | Ein Fenster geht auf, der Kern läuft, ein Testlauf ist grün |
| **W-1** | **Laufwerk** | `laufwerk/win32.ts` aus dem § 3.2-Beweis, Wache im 3-Sekunden-Takt (§ 5), Disc-Typ, Verriegeln, Auswerfen mit Nachsehen | Disc rein → Rippy sagt korrekt, was es ist. Auswerfen wirkt (nachgemessen, nicht geglaubt) |
| **W-2** | **Rippen** | makemkvcon-Aufruf, Parser, Fortschritt, Abbruch, Lesefehler-Warnung, Werkzeug-Beschaffung | Eine DVD und eine Blu-ray laufen durch, verlustfrei |
| **W-3** | **Komprimieren + Ablegen** | HandBrake, Encoder gemessen, Presets, Zielstruktur, NFO, Poster, Medienserver | Ein Film liegt fertig in Jellyfin und ist dort sichtbar |
| **W-4** | **Metadaten-Automatik** | Die vier Quellen aus § 5, Sicherheitsgrad, Nachkorrektur | Fünf verschiedene Discs richtig erkannt, ohne Nachfrage |
| **W-5** | **Oberfläche** | Dashboard, Einstellungen, Logs, Bibliothek, Tray, Windows-Toasts, Taskleisten-Fortschritt | Der Commander bedient Rippy einen Abend lang ohne Rückfrage |
| **W-6** | **Setup + Update** | NSIS, Autostart, Erst-Einrichtung, Selbst-Update, Deinstallation | Frischer Rechner: Setup → Disc rein → MKV raus. Und: drüber-installieren geht |
| **W-7** | **Der Rest** | Audio-CD, ISO-Backup, mehrere Laufwerke, 4K-Schlüsselkette | Je Feature ein Nachweis |
| **W-6** | **Setup + Update** | NSIS, Autostart, Erst-Einrichtung, Selbst-Update gegen das öffentliche Gitea (inkl. Messung der Fest-Adresse für `latest.yml`, Entscheid 6), Lizenztexte beilegen (Entscheid 9), Deinstallation | Frischer Rechner: Setup → Disc rein → MKV raus. Und: drüber-installieren geht |
| **W-7** | **Der Rest** | Audio-CD, ISO-Backup, mehrere Laufwerke, 4K-Schlüsselkette (`werkzeuge/schluessel.ts`), WM_DEVICECHANGE als Wache-Verfeinerung (§ 5) | Je Feature ein Nachweis |
Reihenfolge-Begründung: W-1 bis W-3 sind die Kette, ohne die Rippy nichts tut.
W-4 und W-5 machen sie bequem. W-6 macht sie weitergebbar. W-7 sind die
@@ -932,25 +1058,32 @@ Ergänzungen, die ohne die Kette keinen Sinn hätten.
| Risiko | Bewertung | Behandlung |
|--------|-----------|------------|
| **MakeMKV-Beta-Key läuft Ende September 2026 ab** | hoch × sicher | § 9.1 — Ablaufdatum sichtbar, Warnung 7 Tage vorher, klare Meldung, Dauerlizenz eintragbar. **Das ist der akuteste Punkt im ganzen Dokument.** |
| `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 |
| **MakeMKV-Beta-Key läuft Ende September 2026 ab** | hoch × sicher | § 9.1 — Ablaufdatum sichtbar, Warnung 7 Tage vorher, klare Meldung, Dauerlizenz eintragbar. Einordnung: Dauerzustand seit Sommer 2025, der Key wurde bisher stets verlängert. **Bleibt der akuteste Termin im Dokument.** |
| **Kein installierbares Windows-Rippy zwischen Aufräumen und W-6** | sicher × akzeptiert | Folge von Entscheid 7 („sofort"). Die installierte rc11-EXE läuft lokal weiter; die Docker-Version deckt die VM ab. Bewusst bezahlter Preis |
| Neubau dauert länger als eine Reparatur | sicher | Deshalb Entscheid 2: Die Docker-Version läuft weiter. Es entsteht keine Lücke auf der VM |
| Electron-Paket ~150200 MB | sicher, gering | Ein einmaliger Download. Der Gegenwert ist eine Werkzeugkette statt zweier |
| SmartScreen bei unsignierter EXE | mittel | Entscheid 5: kein Zertifikat. Anleitung + Prüfsumme beim Release |
| **Electron altert schnell** (alle ~8 Wochen neue Hauptversion, nur 3 gepflegt) | sicher × planbar | Pflege-Regel in § 6.8: bei jedem Rippy-Release den Electron-Sprung prüfen. Das Selbst-Update macht das Verteilen billig |
| SmartScreen bei unsignierter EXE | mittel | Entscheid 5: kein Zertifikat. Anleitung + Prüfsumme beim Release — reicht für die Zielgruppe aus Entscheid 9 |
| **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 |
| **Feste `latest.yml`-Adresse im Gitea** | niedrig × messbar | Entscheid 6, ⚠️-Punkt — in W-6 am ersten Release messen; Rückfallebene festes Update-Tag. Eine Bau-Einstellung, keine Programmänderung |
| Updates hängen am Heimnetz des Commanders | niedrig | § 6.8 Regel 3 — ein stummer Server ist eine Protokollzeile, kein Fehler. Wer eine eigene Quelle will, trägt sie ein |
| **Aufräumen von `main` reißt Docker mit** | mittel × vermeidbar | § 11 — drei Teile sauber getrennt, Remote-Worker bleibt, eigener Branch, Ampel nach jedem Schritt |
| koffi + Electron + npm-Install-Sperre | niedrig | § 3.5 gemessen: koffi lädt mit vorgebauten Binärdateien, Electron braucht `install.js` von Hand. Beides steht in der Bau-Anleitung |
| 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 |
| 4K-UHD-Schlüssel | gelöst | Unter Windows holt makemkvcon sie selbst — der strukturelle Vorteil dieser Plattform, gemessen 25.07.2026 |
| ~~`node:sqlite` in Electron ungeprüft~~ | **gelöst** | § 3.4 — am 30.08.2026 im `utilityProcess` von Electron 44 gemessen. Rückfallebene `better-sqlite3` nicht gebraucht |
| ~~Öffentliche Update-Quelle für Externe~~ | **gelöst** | § 3.6 — Gitea ist öffentlich per HTTPS erreichbar, Entscheid 6 nutzt es direkt |
### Alle drei offenen Punkte sind entschieden (30.08.2026)
### Stand der Entscheidungen (30.08.2026, zweite Fassung)
Code-Signing: **nein** (Entscheid 5) · Update-Quelle: **Gitea, auch für
Externe** (Entscheid 6) · alter Windows-Weg: **wird entfernt** (Entscheid 7) ·
der Remote-Worker bleibt bei Docker (Entscheid 8, § 11.1). Was daraus an
Arbeit folgt, steht in § 11.
Alle offenen Punkte der ersten Fassung sind entschieden **und** die Prüfung
hat zwei davon zusätzlich vereinfacht: Code-Signing **nein** (Entscheid 5) ·
Update-Quelle **öffentliches Gitea, direkt** (Entscheid 6, durch Messung § 3.6
von einer Infrastruktur-Frage zu einer Bau-Einstellung geschrumpft) · alter
Windows-Weg **wird sofort entfernt** (Entscheid 7) · Remote-Worker **bleibt
bei Docker** (Entscheid 8) · Zielgruppe **Bekannte mit Link** (Entscheid 9).
Was daraus an Arbeit folgt, steht in § 11 und § 12.
---
@@ -965,6 +1098,8 @@ Arbeit folgt, steht in § 11.
Windows-Lösung besser ist als eine portable, gewinnt die Windows-Lösung.
- **Kein ARM-Fork.** Rippy bleibt ein Eigenbau.
- **Keine Auth.** Einzelplatz, kein Netzdienst — es gibt nichts zu schützen.
- **Kein öffentlicher Auftritt.** Entscheid 9: Weitergabe per Link an
Bekannte, kein Marketing, kein Support-Versprechen an Fremde.
---
@@ -984,4 +1119,4 @@ Begründung:
---
*Rippy v5 · Konzept · 30.08.2026 · Branch `worktree-windows-electron`*
*Rippy v5 · Konzept, zweite Fassung · 30.08.2026 · Branch `worktree-windows-electron`*
+33 -11
View File
@@ -89,25 +89,47 @@ Get-Process -Id $kind -ErrorAction SilentlyContinue # muss LEER sein
---
## Zwei weitere Messungen aus § 3, ohne eigenes Skript
## `sqlite-main.js` + `sqlite-kern.js` — node:sqlite in Electron
**`node:sqlite` ist in Node 24 eingebaut:**
Beantwortet die Frage, die in der ersten Fassung des Konzepts als ⚠️ offen
stand: Electron baut sein Node mit eigenen Flags — ist `node:sqlite` dort
überhaupt vorhanden?
Gemessen am 30.08.2026 mit **Electron 44.0.0**, und zwar im
**utilityProcess** — dem Kontext, in dem Rippy v5 seine Datenbank betreiben
wird (`kern/speicher/db.ts`), nicht bloß im Node-Modus der Binary:
```
node -e "const s=require('node:sqlite'); const db=new s.DatabaseSync(':memory:'); db.exec('CREATE TABLE t (a TEXT)'); db.prepare('INSERT INTO t VALUES (?)').run('geht'); console.log(db.prepare('SELECT a FROM t').get().a)"
geht
KERN-ANTWORT: {"ok":true,"wert":"geht","node":"24.18.1"}
Kern beendet mit 0
```
⚠️ Das ist in **Node 24.19.0** gemessen, nicht in Electron. Electron baut sein
Node mit eigenen Flags — ob `node:sqlite` dort vorhanden ist, ist der erste
Handgriff in Etappe W-0.
**Antwort: ja.** Die im Konzept vorgesehene Rückfallebene `better-sqlite3`
wird nicht gebraucht. (Zur Einordnung: In Node 24.19.0 pur war dieselbe
Messung zuvor ebenfalls grün.)
**npm 11 blockiert Install-Skripte:**
Nachstellen:
```
npm install electron@44 --no-save
node node_modules/electron/install.js
./node_modules/electron/dist/electron.exe sqlite-main.js
```
Die zweite Zeile ist kein Versehen — siehe nächster Abschnitt.
---
## npm 11 blockiert Install-Skripte — und das trifft Electron selbst
```
npm warn allow-scripts koffi@3.1.6 (install: node ./cnoke.cjs -P . --prebuild --release)
```
koffi lädt trotzdem — es bringt vorgebaute Binärdateien mit. Die Warnung
gehört in die Bau-Anleitung, sonst sucht eines Tages jemand an der falschen
Stelle.
koffi lädt trotzdem — es bringt vorgebaute Binärdateien mit. **Electron
trifft die Sperre härter:** Sein Install-Skript lädt die eigentliche
Programmdatei herunter; wird es geblockt, liegt nach `npm install` ein
Paket **ohne `dist/electron.exe`** da, und nichts startet. Am 30.08.2026
beim sqlite-Beweis selbst hineingelaufen; `node node_modules/electron/install.js`
holt die Binary nach. Beides gehört in die Bau-Anleitung, sonst sucht eines
Tages jemand an der falschen Stelle.
+12
View File
@@ -0,0 +1,12 @@
// Läuft als utilityProcess — der Kontext, in dem Rippy v5 seine Datenbank
// betreiben wird (kern/speicher/db.ts laut KONZEPT-WINDOWS.md § 4.2).
try {
const s = require('node:sqlite');
const db = new s.DatabaseSync(':memory:');
db.exec('CREATE TABLE t (a TEXT)');
db.prepare('INSERT INTO t VALUES (?)').run('geht');
const wert = db.prepare('SELECT a FROM t').get().a;
process.parentPort.postMessage({ ok: true, wert: wert, node: process.versions.node });
} catch (e) {
process.parentPort.postMessage({ ok: false, fehler: e.message });
}
+20
View File
@@ -0,0 +1,20 @@
// Beweis: node:sqlite funktioniert im utilityProcess von Electron 44.
// Gemessen 30.08.2026 — siehe README.md in diesem Ordner.
//
// Startet den Kern-Prozess (sqlite-kern.js) genau so, wie Rippy v5 seinen
// Kern starten wird (utilityProcess.fork), und wartet auf dessen Antwort.
const { app, utilityProcess } = require('electron');
const path = require('path');
app.whenReady().then(() => {
const kind = utilityProcess.fork(path.join(__dirname, 'sqlite-kern.js'));
kind.on('message', (antwort) => {
console.log('KERN-ANTWORT: ' + JSON.stringify(antwort));
app.exit(antwort.ok ? 0 : 1);
});
kind.on('exit', (code) => {
console.log('Kern beendet mit ' + code);
if (code !== 0) app.exit(1);
});
setTimeout(() => { console.log('TIMEOUT'); app.exit(2); }, 15000);
});