docs(savepoint): v3.17 - neun Punkte zu, vier Bestandsfehler dazu
Ampel / ampel (push) Successful in 27s
Ampel / ampel (push) Successful in 27s
Der Savepoint trennt wie immer gemessen von vermutet - und stellt zwei Behauptungen aus v3.16 richtig, die sich als falsch erwiesen haben: 1. "Die Namen der Hardware-Presets sind auf der Rippy-VM nicht ermittelbar." Falsch - `--preset-list` nennt sie vollstaendig, auch ohne Hardware-Encoder. Der vermeintliche Blocker fuer Punkt 1 existierte nicht. 2. "Rohschnitt intakt -> 'Neu komprimieren' genuegt." Falsch - can_retry war false, den Knopf gab es nicht. AGENTS.md bekommt zwei neue Lehren aus dieser Sitzung: Hintergrund-Schleifen muessen ihre Fehler melden (ein stiller except hat eine Stunde gekostet), und Netz-Pfade nie ungebremst anfassen - os.path.isdir haengt auf einem toten CIFS im Kernel und laesst sich aus Python nicht abbrechen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -55,7 +55,7 @@ Bibliotheks-APIs: `--help`/Doku prüfen und die Fundstelle im Commit nennen.
|
|||||||
- Kein Proxmox-LXC-Nesting-Workaround — das Projekt lebt bewusst in normalem Docker.
|
- Kein Proxmox-LXC-Nesting-Workaround — das Projekt lebt bewusst in normalem Docker.
|
||||||
- Kein ARM-Fork — Rippy ist ein Eigenbau von Grund auf.
|
- Kein ARM-Fork — Rippy ist ein Eigenbau von Grund auf.
|
||||||
|
|
||||||
## Aktueller Stand (25.07.2026)
|
## Aktueller Stand (26.07.2026)
|
||||||
|
|
||||||
- ✅ **E2E bewiesen (v3.1):** BD-50 komplett durch die Kette (43 GB → 4,8 GB)
|
- ✅ **E2E bewiesen (v3.1):** BD-50 komplett durch die Kette (43 GB → 4,8 GB)
|
||||||
- ✅ **Etappe 13 (v3.2):** Universal-Komfort-Runde — Media-Server-Integration,
|
- ✅ **Etappe 13 (v3.2):** Universal-Komfort-Runde — Media-Server-Integration,
|
||||||
@@ -73,6 +73,11 @@ Bibliotheks-APIs: `--help`/Doku prüfen und die Fundstelle im Commit nennen.
|
|||||||
- ✅ **Etappe 20 (v3.15):** Aufräum-Runde — `/capabilities` 1,010 s → 0,003 s
|
- ✅ **Etappe 20 (v3.15):** Aufräum-Runde — `/capabilities` 1,010 s → 0,003 s
|
||||||
(Ping im Hintergrund), Kompression je Disc-Typ abwählbar (4K verlustfrei),
|
(Ping im Hintergrund), Kompression je Disc-Typ abwählbar (4K verlustfrei),
|
||||||
Wizard empfiehlt nach gemessener CPU, vier tote Routen entfernt
|
Wizard empfiehlt nach gemessener CPU, vier tote Routen entfernt
|
||||||
|
- ✅ **Etappe 21 (v3.17):** Der Blocker externes Encoden ist zu —
|
||||||
|
`RIPPY_PATH_MAP` leitet Rippy aus seinen eigenen Mounts ab, der Installer holt
|
||||||
|
es selbst; Presets kommen vom Worker statt aus dem Quelltext; Dashboard ohne
|
||||||
|
Placebos, mit Restzeit. Dazu vier Bestandsfehler, alle live gemessen (u. a.
|
||||||
|
„Neu komprimieren" ging nie, und `os.path.isdir` hing im Kernel)
|
||||||
- 📝 **Details immer in SAVEPOINT.md** — diese Sektion nennt nur die Etappe
|
- 📝 **Details immer in SAVEPOINT.md** — diese Sektion nennt nur die Etappe
|
||||||
|
|
||||||
## Was diese Sitzungen wiederholt gekostet hat
|
## Was diese Sitzungen wiederholt gekostet hat
|
||||||
@@ -87,3 +92,19 @@ Jedes Mal hätte eine Messung von unter einer Minute gereicht.
|
|||||||
**Und die Umkehrung gilt genauso:** gleiches `st_dev` heißt NICHT gleicher
|
**Und die Umkehrung gilt genauso:** gleiches `st_dev` heißt NICHT gleicher
|
||||||
Mount. Wo eine Eigenschaft ausprobierbar ist, probiere sie aus, statt sie
|
Mount. Wo eine Eigenschaft ausprobierbar ist, probiere sie aus, statt sie
|
||||||
vorherzusagen.
|
vorherzusagen.
|
||||||
|
|
||||||
|
**Ein Hintergrund-Prozess, der still scheitert, ist schlimmer als einer, der
|
||||||
|
laut scheitert** (26.07.2026). Ein `except Exception: pass` in einer
|
||||||
|
Vorrats-Schleife hat eine Stunde gekostet: Der Vorrat blieb leer, die Funktion
|
||||||
|
lief direkt aufgerufen einwandfrei, und der Grund stand nirgends. Gefunden erst
|
||||||
|
über die Thread-Zustände (`/proc/<pid>/task/*/stat`, Zustand `D` = im Kernel
|
||||||
|
blockiert). Jede Hintergrund-Schleife MELDET ihren Fehler, und wer einen Vorrat
|
||||||
|
anlegt, macht sein Alter abfragbar (`GET /health/vorraete`) — sonst ist am
|
||||||
|
Endpunkt selbst nichts zu sehen.
|
||||||
|
|
||||||
|
**Netz-Pfade nie ungebremst anfassen.** `os.path.isdir`/`open` auf einem toten
|
||||||
|
CIFS-Mount blockieren im Kernel und lassen sich aus Python NICHT abbrechen. Ein
|
||||||
|
Kind-Prozess lässt sich abbrechen: `timeout N ls -d <pfad>` (Muster in
|
||||||
|
`mounts.ist_erreichbar` und `rohdaten.verzeichnis_da`). Und „konnte nicht
|
||||||
|
nachsehen" ist etwas anderes als „ist nicht da" — beides zu vermischen erzeugt
|
||||||
|
falsche Aussagen im UI.
|
||||||
|
|||||||
+235
-1
@@ -1,6 +1,240 @@
|
|||||||
# SAVEPOINT — Rippy
|
# SAVEPOINT — Rippy
|
||||||
|
|
||||||
## Aktueller Stand: v3.16 — ÜBERGABE: externes Encoden konnte nie funktionieren (26.07.2026)
|
## Aktueller Stand: v3.17 — der Blocker ist zu, neun Punkte abgearbeitet (26.07.2026)
|
||||||
|
|
||||||
|
> **Deployt und live gegengeprüft.** Auftrag war „lies den Savepoint und lass uns
|
||||||
|
> das Projekt endlich beenden". Die neun Commander-Punkte aus v3.16 sind
|
||||||
|
> abgearbeitet; unterwegs kamen vier Bestandsfehler dazu, die vorher niemand
|
||||||
|
> gesehen hat. Was offen bleibt, steht ganz unten — und es ist wenig.
|
||||||
|
|
||||||
|
### ZUSTAND, gemessen
|
||||||
|
|
||||||
|
| | |
|
||||||
|
|---|---|
|
||||||
|
| Repo + VM | `87537bf`, Ampel **grün**, deployt |
|
||||||
|
| Container | alle 5 `Up`, api/postgres/redis `healthy` |
|
||||||
|
| Tests | **211** grün (vorher 130) |
|
||||||
|
| Job `95afdc89` | `failed`, aber **`can_retry = true`** — die 74,1 GB sind erstmals über das UI erreichbar |
|
||||||
|
| Rohschnitt | `/app/media/rippy/95afdc89-…/title_t00.mkv`, 79.604.951.639 Bytes, intakt |
|
||||||
|
| Platte VM | 148 GB, 107 GB frei |
|
||||||
|
| NAS-Freigabe | eingehängt und antwortend — **aber siehe „NOCH OFFEN" Punkt 1** |
|
||||||
|
|
||||||
|
### DER BLOCKER IST ZU — und er brauchte keine Eingabe vom Nutzer
|
||||||
|
|
||||||
|
`RIPPY_PATH_MAP` wurde von niemandem gesetzt; deshalb konnte externes Encoden
|
||||||
|
**nie** funktionieren. Die Lösung musste nichts erfinden: **Rippy hat die
|
||||||
|
Freigabe selbst eingehängt und kennt ihre Quelle.** Mountpunkt plus Quelle IST
|
||||||
|
das Mapping.
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /worker-setup/pfad-map
|
||||||
|
→ /app/media/rippy=\\192.168.178.62\rippy
|
||||||
|
```
|
||||||
|
|
||||||
|
Live auf der VM abgefragt, Antwortzeit 0,010 s. Beide Windows-Installer holen
|
||||||
|
diesen Wert selbst, prüfen mit `Test-Path`, ob **dieser PC** die Freigabe
|
||||||
|
erreicht, und schreiben ihn in `start-tray.bat` und `start-worker.bat`. Der
|
||||||
|
Commander muss nichts über Container-Pfade wissen — das Feld bleibt leer.
|
||||||
|
|
||||||
|
Ist keine Freigabe eingehängt, sagt der Endpunkt das im Klartext samt Abhilfe,
|
||||||
|
statt ein leeres Mapping zu liefern.
|
||||||
|
|
||||||
|
**Was der Commander jetzt tun kann:** `RippyWorkerSetup.exe` neu holen
|
||||||
|
(Einstellungen → Worker) und laufen lassen. Danach steht bei „Neu komprimieren"
|
||||||
|
sein Ryzen mit avx512f und der RX 9070 XT zur Wahl, und die 74 GB gehen durch,
|
||||||
|
ohne die Disc noch einmal einzulegen.
|
||||||
|
|
||||||
|
### DIE NEUN PUNKTE — Stand jetzt
|
||||||
|
|
||||||
|
| Sein Punkt | Stand |
|
||||||
|
|---|---|
|
||||||
|
| 1. „Bei den Presets soll IMMER das Beste ausgewählt werden" | **erledigt** — Knopf „Bestes wählen", Begründung unter jeder Liste |
|
||||||
|
| 2. „Hier steht noch meine Settings drin" | erledigt (v3.16) |
|
||||||
|
| 3. „Vektorbefehle müssen ausgelesen werden" | erledigt (v3.16) |
|
||||||
|
| 3b. „…wenn der Worker AV1 oder besseres kann, immer diesem empfehlen" | **erledigt** — Hardware-Presets nach Familie, AV1 vor H.265 |
|
||||||
|
| 3c. „…Warnung verschwindet / orange zu grün" | erledigt (v3.16) |
|
||||||
|
| 4. „JIKAN ist drin — wird das genutzt?" | **beantwortet: ja** — und ab jetzt an der richtigen Stelle in der Kette |
|
||||||
|
| 5. „Was wenn der Unterbau nicht Debian ist?" | **erledigt** — Paketwerkzeug wird erkannt |
|
||||||
|
| 6. „Mein PC hat ne dicke Grafikkarte" | **erledigt** — Erkennung (v3.16) + Presets + Pfad-Mapping, die Kette ist vollständig |
|
||||||
|
| 7. „Warum wird der Datei-Browser noch angezeigt" | **erledigt** — eingeklappt |
|
||||||
|
| 8. „Server Status muss dringend überarbeitet werden" | **erledigt** — zwei Placebos entfernt |
|
||||||
|
| 9. „ETA im externen Worker und im Dashboard" | **erledigt** — Restzeit aus gemessenem Fortschritt |
|
||||||
|
|
||||||
|
### GEBAUT — was das Raten beendet
|
||||||
|
|
||||||
|
**Presets kommen vom Worker, nicht aus dem Quelltext.** `caps.py` meldet
|
||||||
|
`HandBrakeCLI --preset-list` (auf der VM: **90 Namen**), `api/presets.py`
|
||||||
|
staffelt daraus die Empfehlung. Kein Punktesystem: für jede Lage eine feste
|
||||||
|
Reihenfolge echter Namen, genommen wird der erste, den der Worker kennt.
|
||||||
|
|
||||||
|
> ⚠️ **Richtigstellung zu v3.16:** Dort stand, die Namen der Hardware-Presets
|
||||||
|
> seien auf der Rippy-VM „nicht ermittelbar", weil deren HandBrake keinen
|
||||||
|
> Hardware-Encoder hat. **Gemessen ist das falsch** — die Kategorie `Hardware/`
|
||||||
|
> steht vollständig in der Liste (`H.265 VCN 2160p 4K`, `AV1 QSV 2160p 4K`,
|
||||||
|
> NVENC, MF). HandBrake trennt zwei Fragen: `--preset-list` nennt alle Presets,
|
||||||
|
> `--help` nur die nutzbaren Encoder. Zwei Fragen, zwei Quellen. Der vermeintliche
|
||||||
|
> Blocker existierte nicht.
|
||||||
|
|
||||||
|
Feinheiten, die zählen: Der Encoder heißt `vce`, das Preset heißt **VCN** — ohne
|
||||||
|
diese Zuordnung liefe die AMD-Karte unter einem Intel-Namen. `vaapi` bekommt
|
||||||
|
bewusst **kein** Hardware-Preset (HandBrake 1.6.1 liefert keines mit), `MF` wird
|
||||||
|
nie empfohlen (Nutzbarkeit nicht ablesbar), und für DVD-Auflösungen gibt es
|
||||||
|
keine Hardware-Presets. Kennt ein Worker keinen der bekannten Namen, sagt das UI
|
||||||
|
„selbst wählen" statt etwas Falsches einzustellen. Und HandBrakes
|
||||||
|
`Invalid preset <Name>` wird jetzt übersetzt — vorher stand da „Code 3".
|
||||||
|
|
||||||
|
**Dashboard: zwei Placebos raus.** Die Karte hieß „Echte Live-Daten" und log an
|
||||||
|
zwei von drei Stellen. „Auslastung: 0 % (Aktiv)" war nicht die CPU-Last, sondern
|
||||||
|
der Job-Fortschritt (bzw. eine feste 15 bzw. 5). Die Verlaufskurve daneben war
|
||||||
|
`Math.random()`. Und „N Worker Online" zählte registrierte Einträge, auch Leichen
|
||||||
|
alter Rebuilds. Jetzt: laufende Phase mit **Restzeit**, jeder erreichbare Worker
|
||||||
|
mit Kernen/Vektorbefehlen/extern, freier Platz mit Warnung, wenn er nicht mehr
|
||||||
|
für eine Disc reicht.
|
||||||
|
|
||||||
|
**Restzeit ehrlich.** Messreihe je Phase (Rip und Kompression haben nichts
|
||||||
|
miteinander zu tun), Stillstand verlängert die Schätzung, unter zwei Messwerten
|
||||||
|
oder 60 Sekunden Spanne gibt es **keine** Aussage — dann steht „Restzeit wird
|
||||||
|
gemessen". Mit den echten 25.07.-Werten gegengerechnet: 1,44 % in 29 min ergibt
|
||||||
|
„noch ca. 1 Tag 23 h".
|
||||||
|
|
||||||
|
**Warnung VOR dem Start.** Wählt man einen externen Encoder, der Quelle oder Ziel
|
||||||
|
nicht erreicht, steht das im Rip-Dialog — nicht erst nach einer Stunde. Bei
|
||||||
|
„Automatisch" wird genannt, welcher Worker die Aufgabe kaputtmachen könnte.
|
||||||
|
|
||||||
|
**Metadaten: exakt schlägt unscharf.** Das Gate 0,55 war nachrechenbar, weil
|
||||||
|
`titel_aehnlichkeit` rein ist:
|
||||||
|
|
||||||
|
```
|
||||||
|
"Alien" vs. "Alien 9" → 0,83 TRIFFT
|
||||||
|
"Inception" vs. "Deception" → 0,78 TRIFFT
|
||||||
|
"Hero" vs. "Heroman" → 0,73 TRIFFT
|
||||||
|
"The Dark Knight" vs. "Dark Knight Rises" → 0,69 TRIFFT
|
||||||
|
```
|
||||||
|
|
||||||
|
Ein Kinofilm, den TMDB verpasst, bekam damit Anime-Metadaten, und OMDb wurde nie
|
||||||
|
gefragt. **Und die Vermutung „das Gate ist zu großzügig" ist trotzdem falsch:**
|
||||||
|
Für den Fall, für den Jikan eingebaut wurde, ist es zu **streng** —
|
||||||
|
„Evangelion 2.22" gegen den MAL-Titel ergibt 0,51 und fällt durch. Eine einzelne
|
||||||
|
Zahl kann beides nicht leisten. Jetzt zwei Schwellen: nur ein praktisch exakter
|
||||||
|
Titel (≥ 0,9) beendet die Kette, ein unscharfer Treffer wird gemerkt, dann kommt
|
||||||
|
OMDb, und erst wenn OMDb nichts hat, gilt er als **Vorschlag** (0,6).
|
||||||
|
|
||||||
|
### VIER BESTANDSFEHLER, die beim Gegenprüfen auffielen
|
||||||
|
|
||||||
|
Alle vier durch **Messen an der laufenden Instanz** gefunden, nicht durch Lesen.
|
||||||
|
|
||||||
|
**1. „Neu komprimieren" ging überhaupt nicht.** Der Savepoint v3.16 schrieb:
|
||||||
|
„Rohschnitt 79,6 GB intakt → ‚Neu komprimieren' genügt". Gemessen war
|
||||||
|
`can_retry = false` — **den Knopf gab es nicht.** Gesucht wurde nur in
|
||||||
|
`/app/temp/raw` und unter dem *aktuellen* `workDir`; der Rip lag aber auf der NAS,
|
||||||
|
weil beim Start eine Wahl **nur für diesen Rip** getroffen worden war, und die
|
||||||
|
Einstellung stand auf leer. Dasselbe in `retry_transcode`: es hätte am falschen
|
||||||
|
Ort gesucht. Neues Modul `rohdaten.py` sieht jetzt an allen Orten nach, die
|
||||||
|
überhaupt in Frage kommen. **Wieder derselbe Fehler:** aus einem Zustandswert
|
||||||
|
(der heutigen Einstellung) auf einen Mechanismus (wohin damals gerippt wurde)
|
||||||
|
geschlossen.
|
||||||
|
|
||||||
|
**2. `os.path.isdir` hing im KERNEL und tötete eine Hintergrund-Schleife.**
|
||||||
|
Zwei Threads des API-Prozesses standen im Zustand **D** (uninterruptible sleep).
|
||||||
|
Die Rohdaten-Schleife startete ihren ersten Durchlauf, während Rippy die
|
||||||
|
CIFS-Freigabe neu einhängte — `asyncio.to_thread` kam nie zurück, die Schleife
|
||||||
|
erreichte ihr `sleep` nie und war **für immer tot**. Ein Timeout um den Aufruf
|
||||||
|
hätte nichts geholfen: ein im Kernel hängender Thread lässt sich aus Python nicht
|
||||||
|
abbrechen. Ein Kind-**Prozess** lässt sich abbrechen — geprüft wird jetzt mit
|
||||||
|
`timeout 4 ls -d`, dasselbe Werkzeug, das `mounts.ist_erreichbar` seit dem
|
||||||
|
24.07. benutzt.
|
||||||
|
|
||||||
|
**3. „Konnte nicht nachsehen" wurde als „ist weg" gewertet.** Nach einem
|
||||||
|
Container-Neustart stallt der erste Zugriff auf die Freigabe; in diesem Fenster
|
||||||
|
verschwand der Knopf „Neu komprimieren", obwohl 74 GB dalagen. Jetzt drei
|
||||||
|
Antworten statt zwei (`da` / `weg` / `unklar` — 124 ist der Rückgabewert von
|
||||||
|
`timeout`), und bei „unklar" wird die letzte bekannte Antwort gehalten.
|
||||||
|
|
||||||
|
**4. Der NAS-Mount kam nach einem Rebuild nicht zurück.** `mounten()` glaubte
|
||||||
|
`os.path.ismount` — und der Mountpunkt existiert im neuen Container weiter
|
||||||
|
(Bind-Mount vom Host), also brach das Wiederherstellen genau dort ab. Dazu öffnet
|
||||||
|
`schreibtest()` eine Datei **ohne Zeitgrenze**: auf einem toten CIFS blockiert das
|
||||||
|
im Kernel. Jetzt entscheidet `ist_erreichbar()` zuerst, und nach dem Mount wird
|
||||||
|
geprüft statt geglaubt (zwei Versuche, dann ehrlicher Fehler).
|
||||||
|
|
||||||
|
### DIE FALLE, DIE DIE MEISTE ZEIT KOSTETE
|
||||||
|
|
||||||
|
**Ein `except Exception: pass` in einer Hintergrund-Schleife.** Der Vorrat blieb
|
||||||
|
leer, die Funktion lief direkt aufgerufen einwandfrei, und **warum** sie im
|
||||||
|
Server nichts tat, war nirgends zu sehen. Erst ein Blick auf die Thread-Zustände
|
||||||
|
in `/proc/<pid>/task/*/stat` brachte das D. Konsequenzen, beide gebaut: Die
|
||||||
|
Schleife **meldet** ihren Fehler jetzt, und es gibt `GET /health/vorraete` — sagt
|
||||||
|
für Ping- und Rohdaten-Vorrat, wie alt der letzte Durchlauf ist. Bleibt so ein
|
||||||
|
Vorrat leer, ist am Endpunkt selbst nämlich **nichts** zu sehen; er antwortet nur
|
||||||
|
dauerhaft „nichts gefunden".
|
||||||
|
|
||||||
|
Merksatz für die nächste Sitzung: Ein Hintergrund-Prozess, der still scheitert,
|
||||||
|
ist schlimmer als einer, der laut scheitert.
|
||||||
|
|
||||||
|
### NOCH OFFEN
|
||||||
|
|
||||||
|
**1. Die NAS-Freigabe antwortet nach einem Container-Neustart oft erst beim
|
||||||
|
zweiten Anlauf — Ursache liegt beim NAS, nicht bei Rippy.** Gemessen: `mount`
|
||||||
|
meldet Rückgabewert 0, `/proc/mounts` zeigt genau eine korrekt aussehende Schicht
|
||||||
|
mit den richtigen Optionen, `ist_erreichbar` bekommt direkt danach eine Antwort —
|
||||||
|
und Sekunden später läuft jeder Zugriff in die Zeitgrenze.
|
||||||
|
`POST /storage-mounts/rippy/repair` stellt sie dann in ~30 s her,
|
||||||
|
reproduzierbar. Das NAS ist per Ping bei 0,47 ms erreichbar. Rippy geht damit
|
||||||
|
jetzt sauber um (harte Zeitgrenzen, zwei Versuche, ehrliche Meldung,
|
||||||
|
Selbstheilung binnen 30 s), aber **die eigentliche Ursache ist nicht gefunden** —
|
||||||
|
Verdacht: das NAS mag sieben Mount-Zyklen in zwanzig Minuten nicht. Zu prüfen,
|
||||||
|
wenn es im Alltag wieder auftritt: SMB-Protokollversion und Sitzungsgrenzen am
|
||||||
|
NAS, und ob ein `repair`-Aufruf beim API-Start als Automatik sinnvoll ist.
|
||||||
|
|
||||||
|
**2. Der externe Worker des Commanders läuft noch mit altem Code.** Er meldet
|
||||||
|
`simd=unbekannt`, `presets: 0`, `pfad_map: None` und stand bei der Prüfung auf
|
||||||
|
`online=false`. Alles, was diese Sitzung gebaut hat, wirkt für ihn erst nach
|
||||||
|
einem Lauf des neuen Installers.
|
||||||
|
|
||||||
|
**3. Live-Gegenprobe der Metadaten-Kette steht aus.** MyAnimeList war während
|
||||||
|
der ganzen Sitzung weg (Jikan antwortete durchweg HTTP 504). Die Arithmetik des
|
||||||
|
Gates ist davon unberührt und in `test_jikan_helpers.py` festgehalten; ein echter
|
||||||
|
Anime-Rip muss es noch bestätigen.
|
||||||
|
|
||||||
|
**4. Aus dem ARM-Vergleich, unverändert nicht gebaut:** ISO-Sicherung für
|
||||||
|
Datenträger, die weder Film noch Audio-CD sind, und **mehrere Laufwerke
|
||||||
|
gleichzeitig** (Rippy sieht sie, ob parallel gerippt wird, ist unbewiesen).
|
||||||
|
|
||||||
|
**5. Ältere Punkte, unverändert gültig:**
|
||||||
|
- Discord-Webhook und MakeMKV-Key liegen im **Klartext** in der settings-Tabelle.
|
||||||
|
Für Heimnetz erwartbar, aber der Webhook ist eine echte Zugangsberechtigung.
|
||||||
|
- **VM-CPU-Typ steht auf `qemu64`** → `host` würde AVX2 freischalten, 2–4×
|
||||||
|
schneller. Anleitung in der README („Rippy schneller machen"). Ein
|
||||||
|
VM-Neustart, nicht gemacht — das ist eine Entscheidung des Commanders.
|
||||||
|
- **`install.sh` ist nie als root durchgelaufen.** Verzeichnisse anlegen,
|
||||||
|
`mount --make-rshared` und die systemd-Unit bleiben ungetestet; sie laufen erst
|
||||||
|
bei einer echten Neuinstallation.
|
||||||
|
- Es gibt **kein TypeScript-Typcheck** im Projekt (`typescript` ist nicht
|
||||||
|
installiert, `npm run build` transpiliert nur mit esbuild). Typfehler im UI
|
||||||
|
fallen nirgends auf. Bewusst nicht geändert: `tsc` in die Ampel zu nehmen färbt
|
||||||
|
sie womöglich wegen Bestandscode rot, und das ist eine Entscheidung.
|
||||||
|
|
||||||
|
### FALLEN DIESER SITZUNG (für die nächste)
|
||||||
|
|
||||||
|
- **Ein Prozess-Zustand `D` in `/proc/<pid>/task/*/stat` heißt: im Kernel
|
||||||
|
blockiert.** Das ist der schnellste Weg, einen hängenden Netz-Zugriff zu
|
||||||
|
finden — schneller als jedes Log.
|
||||||
|
- **`os.path.join` für Container-Pfade ist unter Windows falsch**
|
||||||
|
(`/app/media\rippy`). Dritter Fund derselben Falle; diesmal hat ein Test sie
|
||||||
|
gefunden, nicht die Produktion. Immer `posixpath` für Pfade, die in Container
|
||||||
|
gehen.
|
||||||
|
- **Ein Umlaut-Werkzeug hat `install.ps1` von CRLF auf LF gestellt** — 470
|
||||||
|
Zeilen Diff-Rauschen für eine Änderung von 56. Nach automatisierten
|
||||||
|
Textänderungen an `.ps1` immer `file` gegenprüfen (BOM **und** CRLF).
|
||||||
|
- **Eigene Testerwartungen sind auch Behauptungen.** Zweimal lag der Test falsch
|
||||||
|
und der Code richtig (Confidence 0,3 statt 0,0; „1 Tag 23 h" statt „mehr als 2
|
||||||
|
Tage"). Beide Male hat die Ampel bzw. der lokale Lauf es gefangen.
|
||||||
|
- **Ein Test, der Quelltext-Positionen vergleicht, findet seine eigene Erwähnung
|
||||||
|
im Kommentar.** Verhalten prüfen, nicht Zeichenketten.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Vorheriger Stand: v3.16 — ÜBERGABE: externes Encoden konnte nie funktionieren (26.07.2026)
|
||||||
|
|
||||||
> **Zuerst lesen.** Diese Sitzung endete wegen vollem Kontext. Der Auftrag war
|
> **Zuerst lesen.** Diese Sitzung endete wegen vollem Kontext. Der Auftrag war
|
||||||
> Commander-Feedback aus der ersten Selbst-Einrichtung plus die Diagnose eines
|
> Commander-Feedback aus der ersten Selbst-Einrichtung plus die Diagnose eines
|
||||||
|
|||||||
Reference in New Issue
Block a user