Struktur, Doku und S0-Toolchain fuer das abdulive-Toolkit

Monorepo-Geruest fuer neun Streamer-Tools plus den Ingest-Daemon, der
unter sechs davon liegt. Enthaelt:

- docs/: Ueberblick, Architektur, Twitch-Integration, Datenmodell,
  Roadmap, Setup, Hebel-Analyse und den MVP-Plan "Clip-Knopf"
- docs/projects/: je eine Spezifikation pro Tool
- docs/decisions/: vier ADRs (TS-Monorepo, SQLite, EventSub/IRC, Docker)
- docker/: Image mit ffmpeg und whisper.cpp, abhaengigkeitsfreier
  Entrypoint mit check-env, fetch-model und calibrate
- config/layout.yaml: aus einem VOD-Screenshot eingemessener
  Facecam-Ausschnitt (440x330 oben links, Chat-Overlay ab x=1270)

Noch kein Anwendungscode - Scheibe S0 aus docs/07-mvp-plan.md.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013VTGjd92LsDDWF3frd9FTB
This commit is contained in:
ZeasyAlexandClaude Opus 5 committed 2026-09-09 08:56:09 +02:00
commit d09e2b945a
98 files changed
+3273

No files matched your search

+63
View File
@@ -0,0 +1,63 @@
# Ingest-Daemon (`apps/ingest`)
> Kein eigenes "Tool" im Sinne der Wunschliste, sondern das Fundament, auf dem
> sechs der neun Tools stehen. Wird zuerst gebaut.
## Aufgabe
Ein Prozess, der dauerhaft läuft und alle Datenquellen in einen einheitlichen
Event-Strom übersetzt: schreibt in SQLite, publiziert auf dem Bus.
## Quellen
| Quelle | Verbindung | liefert |
|---|---|---|
| Twitch IRC | `wss://irc-ws.chat.twitch.tv:443` | Chat-Nachrichten mit Tags |
| Twitch EventSub | `wss://eventsub.wss.twitch.tv/ws` | Follows, Subs, Raids, Kategorie, Online/Offline |
| Twitch Helix | REST, Polling 60 s | Viewerzahl, Chatter-Liste (5 min) |
| obs-websocket | `ws://127.0.0.1:4455` | Szenenwechsel, Replay-Buffer-Events |
## Was der Ingest selbst berechnet
**Stream-Sessions.** `stream.online` legt eine `streams`-Zeile an,
`stream.offline` schließt sie. Wenn der Daemon mitten im Stream startet, wird
die laufende Session über `GET /helix/streams` rekonstruiert. Kurze
Unterbrechungen (< 5 min) werden als *dieselbe* Session behandelt — sonst
zerfallen Streams bei jedem Verbindungsabbruch in Fragmente.
**Chat-Spikes.** Gleitendes Fenster über die Nachrichtenrate:
```
rate(t) = Nachrichten in den letzten 15 s
baseline(t) = Median von rate über die letzten 10 min
spike = rate >= max(baseline * 3, baseline + 4)
&& Zeit seit letztem Spike > 60 s
```
Zusätzlich gewichtet: Lach-Emotes (`KEKW`, `LUL`, `OMEGALUL`, Kanal-Emotes),
Ausrufe (`?!`, Großbuchstaben-Anteil), das Wort `clip`. Ergebnis ist ein
`chat.spike`-Event mit `score`. Wer darauf reagiert, entscheidet der Konsument.
> Bei 10 Zuschauern ist die Baseline klein und die Statistik dünn. Der Detektor
> ist deshalb bewusst konservativ und protokolliert *alle* Kandidaten mit Score,
> auch die unter der Schwelle — so lässt sich die Schwelle nachträglich am
> echten Material kalibrieren, statt sie zu raten.
**Anwesenheit.** Aus `GET /helix/chat/chatters` (alle 5 min) plus jeder
Nachricht wird `user_streams` fortgeschrieben: Ersterscheinung, letzte
Aktivität, Minuten. Daraus fällt `streams_present` für jeden User ab.
## Schnittstellen nach außen
- **WS `ws://127.0.0.1:4790`** — Broadcast aller Events als JSON-Zeilen.
Ein Client kann beim Connect `{"since":"<iso-ts>"}` senden und bekommt die
verpassten Events aus der DB nachgeliefert.
- **HTTP `GET /health`** — Status aller vier Verbindungen, für das Dashboard.
## Abnahmekriterien
- Läuft 7 Tage ohne Neustart durch, inklusive Twitch-Reconnects.
- Nach einem erzwungenen Prozess-Kill mitten im Stream: Neustart rekonstruiert
die laufende Session, keine doppelten `streams`-Zeilen, keine doppelten Events.
- Jede Chat-Nachricht eines Test-Streams ist in `chat_messages` (Abgleich gegen
ein parallel mitgeschriebenes Log).