So liest du diesen Issues-Tracker
Bekannte Bugs und offene Baustellen. Jeder Eintrag hat einen Schweregrad, einen Status und — wenn bekannt — einen konkreten Fix-Hinweis.
Schweregrad
- S0 Kritisch – blockiert den Betrieb
- S1 Hoch – deutlich sichtbarer Fehler
- S2 Mittel – Workaround vorhanden
- S3 Niedrig – kosmetisch / Edge Case
Status
- OFFEN Noch nicht angegangen
- IN ARBEIT Fix in Entwicklung
- BLOCKIERT Wartet auf externe Abhängigkeit
- BEHOBEN Deployed, zum Löschen vorgemerkt
Behobene Issues bleiben sichtbar bis zum naechsten grossen Release-Cleanup. So bleibt die Bug-Geschichte nachvollziehbar.
Aktuelle Issues
*Keine offenen Issues — alle bekannten Bugs behoben per v9.3.0.*
Behobene Issues (Sprint 10)
S1 ZapThreads zeigt keine Kommentare — NIP-11 Relay-FilterungBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v9.1.0
Beschreibung: ZapThreads verwirft Relays wegen fehlerhafter NIP-11-Antworten bevor es nach Events sucht. Kombination mit fehlendem Index-Relay: kind:1 Announcements auf nos.lol/damus.io/snort.social werden nicht relay-übergreifend gesucht.
Fix: disable="relayInformation" auf <zap-threads> deaktiviert NIP-11-Filterung. NOSTR_SEARCH_RELAYS: ["wss://relay.nostr.band"] in config.py — indexierendes Relay das Events schnell relay-übergreifend findet.
S1 Slug-Mismatch: habla-Link und ZapThreads zeigten auf falsches NIP-23 EventBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v9.1.0
Beschreibung: _habla_hint_html() und _zapthreads_element() verwendeten meta["slug"] (URL-basiert: folge-7-ki-souveraenitaet-...). _build_nip23() generiert NIP-23 d-Tag aber aus GUID (folge-007-urlaub). Habla-Links und ZapThreads-anchor verwiesen auf nicht-existente Events.
Fix: Beide Funktionen berechnen Slug aus GUID: re.sub(r"[^a-z0-9-]", "-", guid.lower())[:60].
S1 kind:1 Announcements würden bei --force dupliziertBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v9.3.0 (bei Implementierung erkannt)
Beschreibung: kind:1 ist auf Nostr immutabel. --force würde neue kind:1 erzeugen → Spam auf dem Profil.
Fix: Cache-Key nip1:{guid} wird niemals durch --force überschrieben.
S1 publish_to_nostr erhielt rohe Frontmatter-DictsBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v9.1.0
Beschreibung: __main__ übergab load_episodes_from_shownotes() direkt. audio_url mit OP3-Prefix, relative cover_url, kein pub_date_str. Alle published_at-Timestamps waren time.time() → gleich → falsche Reihenfolge im Profil.
Fix: make_meta_from_ep() wird vor publish_to_nostr() angewendet.
S1 ZapThreads Custom Element nie gerendert — falscher ContainerBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v8.0.0
Beschreibung: <div class="zapthreads-container" data-uri="..."> — ZapThreads ignoriert Attribute auf normalem div.
Fix: <zap-threads anchor="naddr1..." relays="..." user="npub1..." disable="relayInformation">.
S2 ZapThreads Script von totem CDN (ERR_CONNECTION_FAILED)BEHOBEN
Status: BEHOBEN v9.3.0
Seit: unbekannt
Beschreibung: zapthreads.dev war laut PageSpeed offline. async statt defer → Custom Element evtl. undefiniert beim Parsen.
Fix: unpkg.com/zapthreads/dist/zapthreads.iife.js, defer.
S2 Habla-URL doppelter PrefixBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v9.3.0 (bei Implementierung erkannt)
Beschreibung: [naddr] wurde durch https://habla.news/a/{naddr} ersetzt, aber NOSTR_HABLA_HINT enthielt bereits https://habla.news/a/[naddr].
Fix: [naddr] → vollständige URL im href, Link-Text "habla.news".
S2 Forced Reflow in setupScrollReveal (55ms)BEHOBEN
Status: BEHOBEN v9.3.0
Seit: v7.0.0
Beschreibung: getBoundingClientRect() innerhalb forEach die auch classList.add() setzt → Layout-Thrashing.
Fix: Alle Reads vor Writes gebündelt.
S2 Forced Reflow in setupParallax (55ms)BEHOBEN
Status: BEHOBEN v9.3.0
Seit: v7.0.0
Beschreibung: img.offsetHeight synchron vor erstem Paint gelesen.
Fix: requestAnimationFrame(() => { h = img.offsetHeight; }).
S2 ep-cover Thumbnails: ~340 KiB unnötigBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v7.0.0
Beschreibung: 670–744px Bilder für 58px Anzeige.
Fix: generate_thumbnails() erzeugt 120px JPEG+WebP; srcset in <picture>.
S2 Bunny Fonts render-blocking (760ms)BEHOBEN
Status: BEHOBEN v9.3.0
Seit: v7.0.0
Beschreibung: display=swap blockiert Rendering bis Schrift geladen.
Fix: display=optional.
S2 DETAILS-Links nicht unterscheidbar für ScreenreaderBEHOBEN
Status: BEHOBEN v9.3.0
Seit: v7.0.0
Beschreibung: 8× "Details →" ohne Kontext.
Fix: aria-label="{title} – Details".
S2 bech32-Decode: Version-Byte-Bug (31 statt 32 Bytes)BEHOBEN
Status: BEHOBEN v9.1.0
Seit: v9.1.0
Beschreibung: bytes(out[1:]) (Segwit) statt bytes(out) (Nostr) → nsec abgelehnt.
Fix: bytes(out).
S2 `style.css` blockiert Rendering — kein Critical-CSS-PfadBEHOBEN
Status: BEHOBEN v8.13.0
Seit: v1.0.0
Beschreibung: <link rel="stylesheet" href="style.css"> im <head> ist render-blocking: Browser rendert keine einzige Pixel bevor style.css vollständig geladen und geparst ist. Bei langsamen Verbindungen (3G, Café-WLAN) bedeutet das mehrere Sekunden weißer/schwarzer Bildschirm — FCP und LCP leiden direkt. 95KB CSS für einen Above-the-Fold-Bereich der nur ~3KB braucht.
Ursache: Kein Critical-CSS-Mechanismus vorhanden. Standard-Pattern für statische Sites, aber messbar suboptimal.
Fix: generate_critical_css() extrahiert 20 kritische Selektoren aus style.css, minifiziert auf ~3KB, bettet sie inline in <head> ein. style.css wird non-blocking geladen (media="print" onload). <noscript>-Fallback für JS-disabled. Browser kann sofort rendern — Hero, Nav, Typografie erscheinen ohne Netzwerkwartezeit.
S3 `twitter:image`, `twitter:title`, `twitter:description` fehlten in `make_head()`BEHOBEN
Status: BEHOBEN v8.13.0
Seit: v1.0.0
Beschreibung: make_head() hatte twitter:card aber keine weiteren Twitter/X-Tags. Nostr-Clients (Amethyst, Primal), Mastodon und ältere Twitter-Clients nutzen twitter: Tags für Link-Previews — nicht ausschließlich og:. Episodenlinks auf Nostr zeigten kein Vorschaubild in allen Clients.
Fix: twitter:image, twitter:title, twitter:description mit denselben Werten wie og: in make_head() ergänzt. Gilt jetzt für Index, Archiv, Changelog, Statistiken. Template-Seiten (Episodenseiten) bereits in v8.12.5 gefixed.
S2 `.card { overflow: hidden }` blockiert horizontalen Table-ScrollBEHOBEN
Status: BEHOBEN v8.12.5
Seit: v7.0.0
Beschreibung: Tabellen in Shownotes (.table-scroll { overflow-x: auto }) scrollten auf Mobile nicht, obwohl der Wrapper korrekt gesetzt war. Ursache: .card hatte overflow: hidden, was alle Kinder-Scroll-Container clippt — overflow-x: auto auf einem Kind wird durch overflow: hidden auf dem Elternelement faktisch deaktiviert.
Warum vorher kein Problem: Tabellen wurden erst ab Folge 7 eingesetzt. Auf Desktop hat der Viewport genug Breite, das Problem tritt nur auf Mobile auf.
Fix: .card { overflow: clip } — clip schneidet visuellen Overflow ab (Noise-Texture-Pseudo-Element, Box-Shadow bleiben korrekt), erzeugt aber keinen Scroll-Container und blockiert keine Kind-Scroll-Elemente. overflow: hidden erzeugt implizit einen neuen Block Formatting Context; overflow: clip nicht.
S2 Share-Button übergibt kein Episodenbild — Android zeigt Podcast-CoverBEHOBEN
Status: BEHOBEN v8.12.5
Seit: v8.12.0
Beschreibung: navigator.share({ title, url }) ohne files[]-Parameter: Android Chrome zeigt im Share-Sheet eine Thumbnail basierend auf dem aktuellen Tab-Kontext (oft der Index-Hero = Podcast-Cover), nicht auf dem og:image der geteilten Episode-URL. RSS-Reader und Messenger zeigen beim Link-Preview das richtige Episodenbild (aus og:image), aber der native Share-Dialog selbst nicht.
Fix: Web Share API Level 2 in template.html: Episodenbild via fetch() holen, als File-Objekt übergeben ({ files: [file] }), navigator.canShare() prüfen. data-share-img Attribut in build.py ergänzt. Dreistufige Fallback-Kette: Level-2-Share → Basic-Share → Clipboard.
S3 `twitter:image` fehlte im Template — Social-Previews unvollständigBEHOBEN
Status: BEHOBEN v8.12.5
Seit: v1.0.0
Beschreibung: template.html hatte twitter:card aber kein twitter:image, twitter:title, twitter:description. Twitter/X, Mastodon und Nostr-Clients nutzen Twitter Card Tags für Link-Previews, nicht ausschließlich og:. Episodenlinks auf Nostr zeigten kein Vorschaubild.
Fix: twitter:image, twitter:title, twitter:description mit denselben {{META_IMG}}/{{PAGE_TITLE}}/{{META_DESC}} Platzhaltern ergänzt.
S2 WCAG 2.1 AA: Labels unter 0.5rem — unter jedem Kontrast nicht lesbarBEHOBEN
Status: BEHOBEN v8.12.3–v8.12.4
Seit: v7.0.0
Beschreibung: op3-kpi-label 0.48rem, werft-kpi-label 0.44rem, kpi-card-label 0.44rem, kpi-stat-label 0.40rem, eng-kpi-label 0.42rem (≈ 6–7px). Unterhalb von 9px ist Uppercase-Mono-Text für Menschen mit durchschnittlicher Sehschärfe auf einem OLED-Display faktisch nicht lesbar, unabhängig vom Kontrastverhältnis.
Fix: Alle Labels auf ≥ 0.62rem (≈ 9.9px) angehoben. --text-dim Opacity 0.50 → 0.65 für WCAG-AA auf --surface-2 (war 4.48:1, jetzt 6.71:1).
S2 8 Inline-Styles in `app.js` — Styling außerhalb CSSBEHOBEN
Status: BEHOBEN v8.12.4
Seit: v7.0.0
Beschreibung: style=-Attribute direkt in innerHTML-Strings: Toast-Titel, Toast-Text, Skip-Icons, Like-Overlay-Buttons, Settings-Groups, OP3-Fehlermeldung, Snapshot-Zeitstempel, Werft-Section-Titel. Verstoß gegen die Trennung von Verhalten (JS) und Darstellung (CSS). Macht Style-Änderungen fehleranfällig (zwei Quellen der Wahrheit).
Fix: Alle 8 Stellen durch CSS-Klassen ersetzt. Einzig verbliebener Inline-Style: bp-transcript-scroll font-size (User-Preference zur Laufzeit, nicht in CSS ausdrückbar), kommentiert.
Status: BEHOBEN v8.12.1 (abflug.sh v7.6.0)
Seit: v7.0.0
Beschreibung: git stash pop wurde mit > /dev/null 2>&1 aufgerufen. Bei einem Merge-Konflikt zwischen lokalen Änderungen und dem Codeberg-Stand schlug stash pop kommentarlos fehl — die lokal geänderten Quelldateien wurden durch die älteren Codeberg-Versionen ersetzt. Der Build lief anschließend durch, pushte aber die alten Dateien. Keine Fehlermeldung, kein sichtbares Signal.
Ursache: Stash/pop ist ein zweiphasiges Muster mit einem unsichtbaren Fehlermodus: git stash speichert lokale Änderungen, git pull lädt Codeberg-Stand (der für dieselben Dateien andere Inhalte hat), git stash pop kann den Conflict nicht auflösen und gibt still auf. Weil beide Ausgaben nach /dev/null umgeleitet wurden, war kein Hinweis sichtbar.
Warum vorher kein Problem: Im normalen Workflow werden Dateien direkt im Repo bearbeitet und sofort per abflug.sh deployed. Codeberg und lokal sind vor dem Edit synchron — stash pop trifft auf keine Konflikte. Das Muster brach erst auf, als Dateien von einer externen Quelle (KI-Session) geliefert und ins Repo kopiert wurden, während Codeberg noch den alten Stand hielt. In diesem Fall unterscheiden sich die Stash-Inhalte vom Pull-Ergebnis — genau das löst den stillen Fehlerpfad aus.
Fix: abflug.sh v7.6.0: git stash/stash pop vollständig entfernt. Neue Reihenfolge: lokale Änderungen per git add . && git commit sichern, dann git pull --rebase. rebase ist deterministisch — bei echtem Konflikt bricht es laut ab (git rebase --abort zum Reset). Kein > /dev/null auf kritischen Operationen.
S2 En-Dash / Pfeil-Zeichen in Python f-strings — Termux SyntaxError-RisikoBEHOBEN
Status: BEHOBEN v8.12.1
Seit: v8.11.0
Beschreibung: build.py L1156 enthielt "—" (U+2014 EM-Dash) und L2090 "→" (U+2192 Pfeil) in echten f-string-Ausdrücken (keine print-Statements). Python 3.12 auf Termux kann bei bestimmten Encoding-Konfigurationen mit Unicode-Literalen in f-strings einen SyntaxError werfen.
Ursache: Anti-Pattern aus AGENTS.md war in neu geschriebenem Code versehentlich eingebaut worden. Der automatisierte Check prüfte nur print()-Zeilen, nicht alle f-string-Nodes.
Fix: L1156: String-Konkatenation mit ASCII "-"; L2090: " -> " statt " → ". Regex-Check verschärft: jetzt alle ast.JoinedStr-Nodes geprüft.
S2 `overflow: hidden` auf `.hero-section` — Gradient-Blend unterbrochenBEHOBEN
Status: BEHOBEN v8.12.1
Seit: unbekannt (mindestens v8.9.0)
Beschreibung: style.css L131 hatte overflow: hidden auf .hero-section, obwohl dies seit v7.0.0 als Anti-Pattern in AGENTS.md dokumentiert ist. Das ::after-Overlay mit linear-gradient zum Seitenhintergrund wurde hart abgeschnitten statt weich auszublenden.
Ursache: Regel wurde bei einem Refactoring wieder eingebaut ohne AGENTS.md-Check.
Fix: overflow: hidden entfernt. Nur position: relative; width: 100% bleibt.
S2 22 `<button>` ohne `type="button"` in dynamisch generiertem HTML (app.js)BEHOBEN
Status: BEHOBEN v8.12.1
Seit: v7.0.0
Beschreibung: Bottom-Player-Toolbar (Mini + Sheet), Zap-Modal, Like-Overlay und Bookmark-Buttons wurden per innerHTML ohne type="button" erzeugt. Standard-Typ ist type="submit" — in einem Form-Kontext würde jeder Klick ein Form-Submit auslösen. HTML5-invalid.
Ursache: type="button" fehlt erfahrungsgemäß in dynamisch erzeugtem HTML, weil es kein Lint-Tool automatisch bemängelt.
Fix: Alle 22 Stellen per Regex ergänzt. Sonderfall: Button in einem Template-String innerhalb eines JS-String-Literals — doppelte Anführungszeichen im type-Attribut erzeugten einen JS-Syntaxfehler; fix: type='button' mit einfachen Anführungszeichen im String-Kontext.
S2 Relative Anker-URLs in content:encodedBEHOBEN
Status: BEHOBEN v8.11.2
Seit: v8.11.0
Beschreibung: href="#lifehacks-details" in <content:encoded> CDATA war relativ. RSS-Reader kennen keine Basis-URL — Links ins Leere. W3C Feed Validator meldete 6 Vorkommen.
Ursache: parse_shownotes_md() gibt Markdown-Links 1:1 aus; im Feed-Kontext fehlt die Seiten-URL als Basis.
Fix: Nach intro_html-Extraktion: re.sub(r'href="#([^"]+)"', lambda m: f'href="{ep_url_plain}#{m.group(1)}"', intro_html).
S2 `<a name="..."></a>` — HTML5-invalidBEHOBEN
Status: BEHOBEN v8.11.2
Seit: v8.11.0
Beschreibung: W3C HTML Checker: 3 Fehler pro Episodenseite — name-Attribut obsolet, href fehlt, Element ungültig.
Ursache: parse_shownotes_md() reichte <a name="..."></a> direkt durch (war Anti-Escape-Workaround).
Fix: Pattern-Match in Shownotes-Parser ersetzt Anker durch <span id="..."></span> — valide, unsichtbar, gleiche Funktion.
S3 Bare `except:` in `_season_sort()`BEHOBEN
Status: BEHOBEN v8.11.2
Seit: v8.7.1
Beschreibung: try: return int(k) / except: return 9999 fing alle Exceptions inkl. SystemExit und KeyboardInterrupt.
Fix: except (ValueError, TypeError): return 9999.
S3 `DeprecationWarning`: `datetime.utcnow()` und `utcfromtimestamp()`BEHOBEN
Status: BEHOBEN v8.11.2
Seit: v8.11.0
Beschreibung: Python 3.12+ gibt bei jedem Build zwei DeprecationWarning aus. In Python 3.14 werden diese zu Fehlern.
Fix: utcnow() → datetime.now(tz=timezone.utc); utcfromtimestamp(t) → datetime.fromtimestamp(t, tz=timezone.utc); timezone zu Imports hinzugefügt.
S3 `version`-Datei seit Sessionen veraltetBEHOBEN
Status: BEHOBEN v8.11.2
Seit: v8.10.1
Beschreibung: version-Datei zeigte 8.10.1 während der aktive Build bereits 8.11.x war. Kein Build-Fehler, aber irreführend beim manuellen Check.
Fix: version → 8.11.2.
S2 seo_description war totes Feld -- kein Durchstich in HTML-MetaBEHOBEN
Status: BEHOBEN v8.11.1
Seit: v8.11.0
Beschreibung: Frontmatter-Schema v2.1 definiert seo_description als SEO-optimierte Kurzbeschreibung (max. 160 Zeichen). Das Feld wurde jedoch an keiner Stelle konsumiert: build_feed() schrieb es nicht in den RSS-Feed, build_episodes() / get_episode_meta() lasen es nicht. Ergebnis: HTML <meta name="description"> verwendete immer sanitize_meta(desc_raw) (= RSS <description> = summary), die selbst bei 3-4 Saetzen deutlich laenger als 160 Zeichen ist und keinen SEO-Fokus hat.
Ursache: Architekturentscheid war unklar dokumentiert ("ist fuer HTML-Meta") -- der Durchstich-Pfad Frontmatter -> RSS -> HTML fehlte.
Fix: build_feed() schreibt seo_description als <itunes:summary>; get_episode_meta() liest itunes:summary bevorzugt als desc_meta; Fallback auf sanitize_meta(desc_raw) wenn Feld leer.
S3 EN-DASH in f-string -- Termux/Android SyntaxError-RisikoBEHOBEN
Status: BEHOBEN v8.11.1
Seit: v8.11.0
Beschreibung: build_stats() enthielt f"{CONFIG['PODCAST_NAME']} - Statistiken" mit U+2013 EN-DASH im f-string-Literal. AGENTS.md Konvention: keine En-Dashes in Python f-strings (Python 3.12+ auf Android/Termux: moeglicher SyntaxError durch konfusable Unicode-Zeichen im Parser). Auf Desktop-Python kein Symptom, erst auf Termux sichtbar.
Ursache: Schreibfehler -- Gedankenstrich statt ASCII-Bindestrich oder Konkatenation.
Fix: f-string durch einfache Konkatenation ersetzt: CONFIG['PODCAST_NAME'] + " - Statistiken".
S3 CHANGELOG.md: v8.10.1 und v8.11.0 mit falschem Heading-LevelBEHOBEN
Status: BEHOBEN v8.11.1
Seit: v8.10.1
Beschreibung: Die Eintrage fuer v8.10.1 und v8.11.0 in docs/CHANGELOG.md verwendeten # vX.Y.Z (H1) statt ## vX.Y.Z (H2). get_version() und parse_changelog_md() erwarten das Format ^## vX.Y.Z per Regex. Direkte Folge: get_version() fand die Versionen nicht als erste Treffer, Anzeige auf changelog.html konnte falsch sortieren.
Ursache: Tippfehler beim manuellen Einfuegen der Eintraege in der KI-Session.
Fix: Beide Eintraege auf ## vX.Y.Z korrigiert; alle bestehenden Eintraege geprueft.
S2 HTML5-Fehler: `&` in `<title>` und `og:title` nicht escapedBEHOBEN
Status: BEHOBEN v8.11.0
Seit: v1.0.0
Beschreibung: Episodentitel mit & (z.B. „Folge 1: Bitcoin ist Komorebi | Nostr & digitale Souveränität") wurden ohne html.escape() direkt in {{PAGE_TITLE}} eingesetzt. In <title> und <meta property="og:title"> erzeugte das & ohne Entity-Kodierung einen W3C Nu Html Checker-Fehler: *"& did not start a character reference"*.
Ursache: meta['title'] kommt aus XML-Parsing (dort korrekt dekodiert), wurde aber beim Einsetzen in den HTML-Template-String nicht erneut escaped.
Fix: html_lib.escape(meta['title']) und html_lib.escape(CONFIG['PODCAST_NAME']) in build_episodes() L2204.
Betroffene Seiten: Alle Episodenseiten mit & im Titel (Folgen 1, 2, 6, 7).
S2 `***fett+kursiv***` erzeugte ungültige HTML5-VerschachtelungBEHOBEN
Status: BEHOBEN v8.11.0
Seit: v8.7.1
Beschreibung: parse_shownotes_md() → inline(): ***text*** wurde als <strong><em>text</strong></em> gerendert statt <strong><em>text</em></strong>. Ungültige Verschachtelung nach HTML5-Spec: Block-Level-Tag-Hierarchie verletzt, Browser-Rendering-Artefakte möglich.
Ursache: **-Pattern wurde vor ***-Pattern geprüft. **text** matchte das äußere **, das innere * wurde als separates <em> behandelt und nach </strong> geschlossen.
Fix: ***-Pattern explizit vor **-Pattern in inline() eingefügt: re.sub(r'\*\*\*(.+?)\*\*\*', r'<strong><em></em></strong>', text).
Hinweis: Kein aktueller Shownotes-Text nutzt ***, aber das Muster ist Teil des unterstützten Markdown-Subsets.
S2 `int()` auf Frontmatter-Werte ohne FehlerbehandlungBEHOBEN
Status: BEHOBEN v8.11.0
Seit: v8.11.0-rc
Beschreibung: build_feed() rief int(ep.get("audio_bytes", 0)) und int(ep.get("audio_dauer", 0)) ohne try/except auf. Wäre ein Frontmatter-Wert kein gültiger Integer (z.B. 1234.5 oder "" durch Tippfehler), crashte der gesamte Build mit ValueError.
Ursache: parse_frontmatter() parst reine Ganzzahlen korrekt als int, liefert aber bei gemischten Werten (z.B. 1234.5) einen str. int("1234.5") wirft ValueError.
Fix: Beide int()-Aufrufe in try/except (ValueError, TypeError) gewrappt, Fallback 0.
S0 style.css im falschen Verzeichnis — Font nie geladenBEHOBEN
Status: BEHOBEN v8.9.1
Seit: v8.9.0
Beschreibung: Das aktualisierte CSS (Plus Jakarta Sans, Font-Tokens, tabular-nums) landete beim Kopieren in assets/js/style.css statt assets/css/style.css. Browser lud immer noch den alten v7.8.0-Stand mit Outfit. Keine sichtbare Änderung trotz korrektem HTML-Link /assets/css/style.css?v=....
Ursache: Manueller Kopierfehler bei der Dateiablage.
Fix: Korrekten Stand nach assets/css/style.css verschoben, Stray-File in assets/js/ entfernt.
S1 build.py make_head() — Outfit-Font hardcoded, nicht von template.html überschreibbarBEHOBEN
Status: BEHOBEN v8.9.1
Seit: v8.9.0
Beschreibung: make_head() in build.py hatte die Bunny-CDN-URL mit outfit:300,400,500,600,700 hardcoded. Alle via make_head() generierten Seiten (index.html, changelog.html, statistiken.html, archive.html) luden immer Outfit — egal was in template.html stand. Nur Episodenseiten, die template.html direkt nutzen, hätten Plus Jakarta Sans bekommen.
Fix: make_head() Bunny-CDN-URL auf plus-jakarta-sans:300,400,500,600,700 aktualisiert.
S2 Bookmark-Icon zu klein — optisch aus der ReiheBEHOBEN
Status: BEHOBEN v8.10.0
Seit: v7.2.0
Beschreibung: Das 🔖-Icon im Player-Sheet war sichtbar kleiner als die Icons der anderen Action-Buttons (♡ Like, ⚡ Zap, ↗ Teilen, ⚙️ Settings). Text-Label "Bookmark" stand nicht auf gleicher Höhe. Ursache: .bp-bm-icon hatte keine font-size — erbte 0.56rem vom Button statt 1.1rem wie alle anderen Icons.
Ursache: Der Bookmark-Button wird dynamisch via document.createElement angehängt (nach DOM-Ready), die entsprechende CSS-Klasse hatte keine font-size explizit gesetzt.
Fix: .bp-bm-icon { font-size: 1.1rem; display: block; } ergänzt.
S2 CO-PILOT-Sektion klebt am CTA-BlockBEHOBEN
Status: BEHOBEN v8.10.0
Seit: v8.0.0
Beschreibung: Die Sektion "CO-PILOT — KI-ASSISTENZ" im Werft-Tab hatte keinen sichtbaren Abstand zum darüber liegenden "Hangar öffnen"-CTA-Block inklusive "Quellcode, Issues und Commit-Historie — öffentlich einsehbar." Die beiden Blöcke klebten direkt aneinander.
Ursache: .werft-cta hatte nur margin-top aber kein margin-bottom. Die CO-PILOT-Sektion wird von einem separaten IIFE (KpiPanels) nach dem Haupt-render() angehängt — der Abstand lag ausschließlich beim CTA.
Fix: margin-bottom: 56px auf .werft-cta ergänzt.
S1 Kapitelbilder-Toggle ohne WirkungBEHOBEN
Status: BEHOBEN v8.10.0
Seit: v7.2.0
Beschreibung: Das Setting "Kapitel-Bilder" in den Player-Einstellungen hatte keinerlei Effekt. Kapitelbilder wurden immer angezeigt, egal ob der Toggle an oder aus war.
Ursache: Zwei Bugs gleichzeitig: (1) renderSheetChaps() las SettingsStore.get('chapterImages') nie ab — der Wert wurde gespeichert aber nie konsumiert. (2) onSettingChange('chapterImages') enthielt nur /* applied on next chapter load */ — Änderung wirkte also erst nach manuellem Track-Wechsel.
Fix: renderSheetChaps() prüft SettingsStore.get('chapterImages') !== false vor dem Rendern von Bildern. onSettingChange ruft bei chapterImages sofort renderSheetChaps() auf.
S2 Shownotes-Tabellen auf dunklem Hintergrund nicht lesbarBEHOBEN
Status: BEHOBEN v8.9.0
Seit: v8.7.1
Beschreibung: Markdown-Tabellen in Shownotes (shownotes-table) hatten kaum sichtbaren Kontrast zum Seitenhintergrund. Header-Zeile nur minimal abgehoben, keine Zeilen-Trennung erkennbar, kein Zebra-Muster. Für Inhalte wie die Cloud-vs-Lokal-Kalkulation (mit Zahlen und Vergleichsspalten) praktisch unlesbar.
Fix: Kompletter Tabellen-Stil: Zebra-Muster (odd/even), border-warm-Außenrahmen, Space-Mono-Header in dawn-amber, Hover-State, explizites vertical-align: top.
S2 Kein vertikaler Rhythmus — Sektionen zu dichtBEHOBEN
Status: BEHOBEN v8.9.0
Seit: v7.0.0
Beschreibung: Abstände zwischen Haupt-Sektionen zu gering. Besonders CO-PILOT-Sektion im Werft-Tab klebte am vorherigen Block, Logbuch-Einträge flossen ohne Luft ineinander, KPI-Akkordeon-Panel klebte am nächsten Content.
Fix: .section-divider 22px→44px, .werft-section 32px→52px, .log-entry 24px→36px, .changelog-section 14px→28px, .kpi-accordion 24px→40px.
S2 Zifferndarstellung in KPI-Cards inkonsistent (proportionale Ziffern)BEHOBEN
Status: BEHOBEN v8.9.0
Seit: v7.0.0
Beschreibung: Zahlen in KPI-Cards (Sprint-Metriken, Werft-KPIs, OP3-Stats) nutzten proportionale Mediävalziffern. Bei Werten unterschiedlicher Länge (z.B. "15" vs "174") unterschiedliche optische Gewichtung, Ziffern "sprangen" auf ihrer Baseline.
Ursache: Inter/Outfit/Plus Jakarta Sans haben OpenType-Features für tabular-nums — ohne explizites Aktivieren werden proportionale Ziffern gerendert.
Fix: font-variant-numeric: tabular-nums lining-nums; font-feature-settings: "tnum" 1, "lnum" 1 auf alle KPI/Metric-Selektoren.
S2 Font-Tokens fehlten — Typeface-Änderung erforderte 20+ StellenBEHOBEN
Status: BEHOBEN v8.9.0
Seit: v7.0.0
Beschreibung: Über 160 font-family-Inline-Strings im CSS verteilt ('Outfit', 'Syne', 'Space Mono'). Jeder Font-Wechsel erforderte globales Search & Replace mit Risiko von Regressions. Kein Single Point of Control.
Fix: :root-Tokens --font-body, --font-display, --font-mono eingeführt. Alle 160+ Inline-Strings auf var(--font-*) umgestellt. Änderung jetzt an 3 Stellen: :root, build.py make_head(), template.html.
S2 Body-Font Outfit — suboptimale Ziffernoptik für KPI-ContentBEHOBEN
Status: BEHOBEN v8.9.0
Seit: v7.0.0
Beschreibung: Outfit hatte schwaches optisches Gewicht bei Zahlen und eine niedrigere x-Höhe als ideal für kleine Schriftgrößen (0.7–0.9rem). Bei KPI-Labels und Datenwerten auf kleinen Screens suboptimale Lesbarkeit.
Fix: Outfit → Plus Jakarta Sans (schärfere x-Höhe, ausgeglichenere Ziffernformen, Awwwards-kompatibler Stack mit Syne).
S1 Tab-Bug — `[hidden]`-Attribut überschreibt alle JS-Toggle-StrategienBEHOBEN
Status: BEHOBEN v8.7.1 / v8.1.0 / v7.9.0
Seit: v7.4.0
Beschreibung: Logbuch-Tabs schalteten nicht korrekt um. Root-Cause: CSS-Regel [hidden] { display: none !important } schlägt laut CSS-Kaskade auch style.display und style.cssText-Inline-Styles. Mehrfach als "behoben" markiert, dann regressiert (v7.9.0 → v8.1.0 → v8.7.1). Letzte Manifestation: hidden-Attribut direkt im generierten Tab-Panel-HTML.
Fix (endgültig v8.1.0): Neues Tab-System ausschließlich mit .is-active-Klasse. Kein hidden-Attribut mehr im HTML, kein style.display. [hidden] { display: none !important } nur noch für semantisch-HTML-hidden, nicht für JS-Toggle.
S1 parse_roadmap_md() — letztes Sprint-Div nie geschlossenBEHOBEN
Status: BEHOBEN v8.2.1
Seit: v8.0.0
Beschreibung: Das letzte Sprint-<div> in parse_roadmap_md() wurde nur durch ein abschließendes --- geschlossen. Da ROADMAP.md keinen --- nach dem letzten Sprint hatte, blieb der Block offen. <div class="content-body"> und </main> waren im generierten HTML invalide.
Fix: if in_sprint: html += "</div>" am Funktionsende ergänzt.
S1 parse_issues_md() — stray `<div>`, unkorrekte H1-Behandlung, letztes Issue offenBEHOBEN
Status: BEHOBEN v8.2.0
Seit: v8.0.0
Beschreibung: Drei Bugs in parse_issues_md(): (1) --- Trennzeichen schloss Karten-Divs auch wenn keine Karte offen war → stray </div>. (2) # Datei-Header-Zeilen wurden als Body-Text gerendert statt übersprungen. (3) Letztes Issue wurde nie geschlossen (kein --- am Dateiende).
Fix: in_card-Tracking, H1-Skip, explizites Schließen am Funktionsende.
S1 W3C-Validierungsfehler — `<section>` ohne direktes HeadingBEHOBEN
Status: BEHOBEN v8.2.0
Seit: v8.0.0
Beschreibung: Roadmap-, Issues- und Werft-Tab-Container verwendeten <section> ohne direktes <h2>/<h3> im Scope. W3C Nu Html Checker: "warning: Section lacks heading."
Fix: <section> in Tab-Panels durch <div> ersetzt.
S1 Sensible Build-Daten auf allen Seiten sichtbarBEHOBEN
Status: BEHOBEN v8.4.0
Seit: v8.3.0
Beschreibung: claudeData (KI-Stunden, Sessionen), changelogKpis, issuesKpis, engineData (Git-SHA, Unix-Timestamps, Repo-Größe) waren im HTML-Source jeder Episodenseite als window.HU_CONFIG sichtbar. Datenschutz-Problem: Arbeitszeitmuster, Fingerabdrücke, Metadaten öffentlich reproduzierbar.
Fix: make_hu_config(changelog_page=False) — sensible Felder nur auf changelog.html. Alle anderen Seiten: {buildMonth: "YYYY-MM"} statt vollem engineData.
S2 KI-Sektion Claude-spezifisch — andere LLMs nicht abbildbarBEHOBEN
Status: BEHOBEN v8.6.0
Seit: v8.3.0
Beschreibung: Config-Keys CLAUDE_* und Sektion "CLAUDE AI NUTZUNG" setzten Claude als einziges KI-Tool voraus. Verwendung von ChatGPT, Gemini etc. parallel nicht dokumentierbar.
Fix: CLAUDE_* → KI_*, Sektion umbenannt in "CO-PILOT — KI-ASSISTENZ", KI_TOOLS als Freitext-Feld.
S1 Claude-Nutzungsdaten via CSV — Free-Tier hat keinen ExportBEHOBEN
Status: BEHOBEN v8.5.0
Seit: v8.3.0
Beschreibung: parse_claude_csv() erwartete CSV-Export aus der Anthropic Console. claude.ai Free/Pro hat keinen API-Zugang und damit keinen Token-Export. Build lief ohne claude_usage.csv fehlerhaft oder mit Dummy-Daten.
Fix: CSV-basierter Ansatz komplett entfernt. Manuelle Pflege via KI_SESSIONS, KI_HOURS, KI_HOURS_HUMAN in config.py. Schätzwerte klar als solche gekennzeichnet.
S1 OP3 API: showUuid vs. podcastGuid verwechseltBEHOBEN
Status: BEHOBEN v7.2.4
Seit: v7.2.0
Beschreibung: Download- und Query-Endpoints der OP3-API erwarten die interne showUuid, nicht die podcastGuid aus dem RSS-Feed. Alle Requests gaben HTTP 400 zurück.
Fix: show_uuid = show.get("showUuid") nach initialem /shows/{podcastGuid}-Fetch.
S1 OP3 API: falsche Endpunkt-Pfade (Plural/Singular, Datumsformat)BEHOBEN
Status: BEHOBEN v7.2.3
Seit: v7.2.0
Beschreibung: Drei Endpunkte falsch: downloads/shows/ (Plural) statt downloads/show/ (Singular), Datumsformat YYYY-MM-DD statt YYYY-MM, falsches Query-Endpoint-Schema.
Fix: Alle drei Endpunkte korrigiert.
S1 OP3 Datenformat — TSV statt JSON, dict statt rowsBEHOBEN
Status: BEHOBEN v7.2.5
Seit: v7.2.3
Beschreibung: /downloads/show/ liefert TSV, kein JSON. top-apps-for-show liefert appDownloads-Dict, kein rows-Array. JS erwartete .rows-Zugriff.
Fix: TSV-Endpoint aus Statistik-Nutzung entfernt, dict-Mapping korrigiert.
S1 OP3 ReferenceError: dlData nicht definiertBEHOBEN
Status: BEHOBEN v7.2.6
Seit: v7.2.5
Beschreibung: dlData noch aus alter fetch()-Version referenziert (if (dlData?.rows?.length)), nach Refactoring nicht mehr vorhanden. Warf ReferenceError im try-Block — catch zeigte irreführend "OP3 API nicht erreichbar".
Fix: Veralteten Block entfernt, Sparkline aus monthly.weeklyDownloads aufgebaut.
S2 OP3 Token in config.py und HTML-Source sichtbarBEHOBEN
Status: BEHOBEN v7.2.2
Seit: v7.2.0
Beschreibung: OP3_TOKEN war in config.py und wurde in window.HU_CONFIG ins HTML eingebettet — Token im Browser-Quelltext öffentlich sichtbar.
Fix: Token nur noch als os.environ["OP3_TOKEN"] zur Build-Zeit — nie in Git, nie im HTML.
S1 Transkript-Tab leer — IIFE-Scope-BugBEHOBEN
Status: BEHOBEN v7.6.4 / v7.5.1
Seit: v7.5.0
Beschreibung: Transkript im Player-Sheet wurde nicht geladen. initSheetTabs() lief bei DOMContentLoaded bevor Player.inject() #bp-sheet ins DOM schrieb. getElementById("bp-sheet") war null, früher Return, kein Click-Listener. Fehler lautlos, kein Console-Error.
Fix: Event-Delegation auf document statt Init-Guard auf spezifischem Element.
S1 Player-Bar auf Home und Archiv nie sichtbarBEHOBEN
Status: BEHOBEN v7.6.6
Seit: v7.0.0
Beschreibung: Player.inject() lief nur wenn audio.card-audio im DOM vorhanden — das gibt es nur auf Episodenseiten. Auf Home (index.html) und Archiv (archive.html) wurde #bp-bar nie erzeugt. Audio lief (unsichtbar), aber keinerlei Bedienelemente.
Fix: Guard entfernt, Player.inject() bedingungslos.
S1 Doppelter Play-Handler — Audio startete und stoppte sofortBEHOBEN
Status: BEHOBEN v7.6.7
Seit: v7.0.0
Beschreibung: Inline-Script in build_index() UND setupEpisodeCards() in app.js feuerten gleichzeitig auf denselben Play-Buttons. Klick startete Audio → zweiter Handler stoppte es sofort.
Fix: Inline-Script in build_index() vollständig entfernt. setupEpisodeCards() ist einzige Quelle für Card-Interaktionen.
S2 Like-Button auf Latest-Episode-Card nicht funktionalBEHOBEN
Status: BEHOBEN v7.1.0
Seit: v7.0.0
Beschreibung: setupEpisodeCards() nutzte querySelectorAll(".episode-card") — erfasste .latest-episode-card (Featured Card auf der Startseite) nicht. Like-Button auf der obersten Karte hatte keinen Handler.
Fix: querySelectorAll(".episode-card, .latest-episode-card").
S2 Nav auf Episodenseiten — inkonsistente Anker-LinksBEHOBEN
Status: BEHOBEN v7.4.2
Seit: v7.4.0
Beschreibung: template.html hatte noch 6 Nav-Links inklusive #Abonnieren und #NeusteFolge als Anker. Auf Nicht-Index-Seiten führten diese Links nirgendwo hin (Anker existieren nur auf index.html). Konfus für Nutzer und Screenreader.
Fix: Nav auf 4 echte Seiten (Start/Hangar/Logbuch/Radarbild) reduziert, konsistent auf allen Seitentypen.
S2 Player.inject() auf Logbuch/Radarbild — "keine Datei ausgewählt"-BugBEHOBEN
Status: BEHOBEN v7.4.2
Seit: v7.4.0
Beschreibung: Player.inject() lief auf Allen Seiten nach Guard-Entfernung (v7.6.6). Auf Logbuch und Radarbild ohne Audio-Elemente: leere Player-Bar mit "keine Datei ausgewählt" erschien kurz.
Fix: Guard nur für vollständigen Inject, nicht für Bar-Initialisierung.
S2 Footer auf statistiken.html fehlteBEHOBEN
Status: BEHOBEN v7.4.0
Seit: v7.3.0
Beschreibung: Die Statistiken-Seite wurde ohne Footer generiert — make_footer() nicht in build_stats() aufgerufen.
Fix: make_footer(version) in build_stats() ergänzt.
S3 W3C-Fehler — Pipe in Bunny-Fonts-URL nicht URL-encodedBEHOBEN
Status: BEHOBEN v7.3.3
Seit: v7.0.0
Beschreibung: | zwischen Fontnamen in der Bunny-CDN-URL war nicht als %7C encoded, & nicht als & — W3C Nu Html Checker: Validierungsfehler auf allen generierten Seiten.
Fix: URL-Encoding in make_head() korrigiert.
S2 Inline `style="..."` in build.py und app.js — CSS-Separation verletztBEHOBEN
Status: BEHOBEN v7.3.1–v7.3.2
Seit: v7.0.0
Beschreibung: Ca. 15 Stellen in build.py und app.js nutzten style.cssText oder inline style=-Attribute statt CSS-Klassen. Verhinderte einheitliches Theming, schwer zu überschreiben.
Fix: Alle inline Styles auf dedizierte CSS-Klassen migriert.
S2 abflug.sh — kein `set -e`, Push bei fehlgeschlagenem Build möglichBEHOBEN
Status: BEHOBEN v7.5.0
Seit: Projektstart
Beschreibung: abflug.sh hatte kein set -e und kein set -o pipefail. Bei Python-Fehlern oder fehlgeschlagenem Build wurde trotzdem gepusht — defekte Builds auf Codeberg Pages deployed.
Fix: set -e + set -o pipefail am Script-Anfang.
S2 Kapitel-Highlighting — Off-by-one durch GleitkommaBEHOBEN
Status: BEHOBEN v7.6.9
Seit: v7.6.x
Beschreibung: Aktives Kapitel im Sheet (chapter-item.active) sprang auf falschen Eintrag oder reagierte verzögert. highlightChapter() verglich aud.currentTime mit parseFloat(dataset.start) — Gleitkomma-Rounding (180.0 vs. 179.98) führt zu Off-by-one bei kurzen Kapiteln.
Fix: Toleranz von 0.5s beim Vergleich.
S3 Service-Worker Cache nach Deploy manchmal veraltetBEHOBEN
Status: BEHOBEN v7.8.0
Seit: Projektstart
Beschreibung: Nutzer sahen nach Deploy gelegentlich ältere Versionen. skipWaiting() gesetzt, aber Browser warteten manchmal Tab-Reload für SW-Aktivierung.
Fix: clients.claim() in activate-Handler, SW-Update-Toast mit aria-live=polite.
S3 Console.log zeigte hardcodierte Version statt aktuelleBEHOBEN
Status: BEHOBEN v7.6.7
Seit: v7.0.0
Beschreibung: Startup-Log in app.js hatte Version hardcoded (v7.0.0) statt window.HU_CONFIG.version zu lesen.
Fix: Template-String liest HU_CONFIG?.version.
S2 `parseFloat()` kann `HH:MM:SS`-Timestamps nicht parsenBEHOBEN
Status: BEHOBEN v7.2.x
Seit: v7.2.0
Beschreibung: Chapter-JSON enthält Timestamps als "01:23:45" Strings. parseFloat("01:23:45") gibt 1 zurück (parst bis zum ersten Nicht-Ziffern-Zeichen). Kapitel sprangen zur falschen Zeit.
Fix: Dedizierte parseChTime() Funktion die HH:MM:SS, MM:SS und Sekunden-Zahl als Fallback korrekt auflöst.
S2 `contain: *` auf Cards — box-shadow abgeschnittenBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: Einsatz von contain: layout oder contain: strict auf .card-Elementen schnitt box-shadow ab (CSS-Spec: contain erstellt neuen Stacking Context). Cards sahen abgehackt aus.
Fix: contain komplett von Cards entfernt. In AGENTS.md als kritisches Anti-Pattern dokumentiert.
S2 `overflow: hidden` auf `.hero-section` — Gradient-Blend unterbrochenBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: overflow: hidden auf der Hero-Sektion unterbrach den Gradient-Blend-Effekt zum Seitenhintergrund. Harter optischer Abschnitt statt sanftem Übergang.
Fix: overflow: hidden auf .hero-section entfernt. Anti-Pattern in AGENTS.md.
S2 Scroll-Reveal `opacity: 0` auf erster Card — Content bei langsamem JS unsichtbarBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: .js .card { opacity: 0 } für Scroll-Reveal-Animationen traf auch die erste Card. Wenn JS langsam initialisierte oder blockiert war, blieb die erste Card dauerhaft unsichtbar.
Fix: .js .card:first-of-type { opacity: 1 !important; transform: none !important } als Ausnahme. Anti-Pattern in AGENTS.md.
S2 `card-link-overlay` mit `position: absolute; inset: 0` auf interaktiven CardsBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: Overlay-Links über die gesamte Card fingen alle Click-Events ab — Buttons, Like-Icons, Zap-Buttons innerhalb der Card reagierten nicht mehr.
Fix: Overlay-Pattern auf Cards mit interaktiven Kindern entfernt. Anti-Pattern in AGENTS.md.
S3 `localStorage` ohne try/catch — Crash im Private-ModeBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: Direkte localStorage-Zugriffe in einigen Stellen ohne try/catch. In bestimmten Browsern im Inkognito-Modus oder bei vollen Storage-Quotas wirft localStorage.setItem() eine Exception — unkontrollierter Crash.
Fix: Alle localStorage-Zugriffe in try/catch. Anti-Pattern in AGENTS.md.
S3 `<button>` ohne `type="button"` — unbeabsichtigtes Form-SubmitBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.0.0
Beschreibung: Mehrere <button>-Elemente ohne explizites type="button". Standard ist type="submit" — in einem Form-Kontext würde ein Klick das Form submitten statt den Handler auszuführen.
Fix: Alle Buttons im dynamisch generierten HTML explizit mit type="button". Anti-Pattern in AGENTS.md.
S3 Kontrast-Mängel — Nav, Beschreibungen, Buttons unter WCAG AABEHOBEN
Status: BEHOBEN v7.1.0
Seit: v7.0.0
Beschreibung: Nav-Links mit --text-faint (22% Opacity), Episode-Beschreibungen mit 50% Opacity, Like- und Details-Buttons kaum sichtbar. Auf OLED-Displays faktisch unsichtbar.
Fix: Nav → --text-dim (50%), ep-desc → --text mit 70% Opacity, Buttons angehoben.
S3 Bullets im Logbuch unsichtbar — CSS-ResetBEHOBEN
Status: BEHOBEN v7.1.0
Seit: v7.4.0
Beschreibung: Globaler CSS-Reset (list-style: none) entfernte alle Bullets. Changelog-Einträge mit <ul> hatten keine sichtbaren Listenpunkte.
Fix: .log-entry ul { list-style: disc; padding-left: 1.2em }, ::marker in Sunrise-Orange.
S3 `setInterval` ohne `clearInterval` beim Stoppen — Memory LeakBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.2.0
Beschreibung: Sleep-Timer und V4V-Streaming nutzten setInterval ohne garantiertes clearInterval bei Stop/Pause/Destroy. Mehrfaches Starten/Stoppen akkumulierte laufende Intervals.
Fix: Alle setInterval-Stellen auf clearInterval-Pattern umgestellt. Anti-Pattern in AGENTS.md.
S2 `patchPlayerForSprint34` vor `Player.inject()` aufgerufen — Null-FehlerBEHOBEN
Status: BEHOBEN (Anti-Pattern dokumentiert)
Seit: v7.2.0
Beschreibung: Sprint-3/4-Patch-Funktion wurde an einer Stelle vor Player.inject() aufgerufen — DOM-Elemente (#bp-bar, #bp-sheet) existierten noch nicht, alle getElementById-Calls gaben null zurück, null-Referenz-Fehler folgten.
Fix: Aufruf-Reihenfolge korrigiert. Anti-Pattern in AGENTS.md.
S3 Hardcoded Podcast-Name und Pfade im JSBEHOBEN
Status: BEHOBEN v7.3.1
Seit: v7.0.0
Beschreibung: "Herr Urlaub..." und /statistiken.html waren direkt in app.js hardcoded. Bei Umbenennung des Podcasts oder der Statistik-Seite musste JS manuell angepasst werden.
Fix: window.HU_CONFIG.podcastName und window.HU_CONFIG.statsPage.
*Zuletzt aktualisiert: v8.13.0 — 12.03.2026*