# Migrationsplan: Gateway-Patch in das produktive Telegram-Plugin einspielen

**Nur Plan. Nichts davon ist ausgeführt.** Jeder Schritt am Produktivsystem braucht Kais' ausdrückliche Freigabe.
Ausführen darf ihn nur, wer die Hauptsitzung neu starten darf (Restart über `aria.service`); kein `claude -p` auf dem
Server (startet das Plugin ein zweites Mal und macht die Hauptsitzung taub).

## Ausgangslage (geprüft, nur lesend, 2026-10-24)

| Punkt | Befund |
|---|---|
| Plugin-Verzeichnis | `/home/aria/.claude/plugins/cache/claude-plugins-official/telegram/0.0.6/` |
| `server.ts` | 41062 Bytes, sha256 `a20b9d6dbb61ad6130b9b8dacd78509407f809fae7e5839907c857b449949f3d`, enthält den lokalen Supabase-Patch (Marker `aria-patch: supabase log inbound`) |
| Start | `.mcp.json`: `bun run --cwd ${CLAUDE_PLUGIN_ROOT} --shell=bun --silent start`; `package.json`: `"start": "bun install --no-summary && bun server.ts"` (bei **jedem** Start läuft `bun install`) |
| Token, Allowlist | `~/.claude/channels/telegram/.env` (wird von `server.ts` für noch nicht gesetzte Variablen geladen), `access.json` |
| Poller | genau einer (`bun server.ts`, cwd = Plugin-Verzeichnis; Phase A per `ps` und `/proc/<pid>/cwd`) |
| Plugin-Updates | neue Version = neues Verzeichnis (`…/telegram/<version>/`), alte Verzeichnisse werden nach Nichtnutzung entfernt (`.in_use`, `.last_inuse_sweep`) [V: Mechanik aus Dateinamen geschlossen]. Lokale Änderungen gehen dabei verloren (siehe Kommentar des Supabase-Patches) |

## Voraussetzungen vor Schritt 1

1. Freigaben: Produktivänderung (Kais), E5 (Ausfallregel), E8 (Pfade, Schlüssel), E24 (Gateway liest `access.json`),
   E34 (wo die Variablen stehen). Für `active` zusätzlich E1–E4, E27.
2. Installierte Version prüfen: `sha256sum …/0.0.6/server.ts` = `a20b9d6d…`. Weicht sie ab (Update!), **nicht**
   einspielen: Patch gegen die neue Version neu bauen (neue `server.prod-<version>.ts`, Tests anpassen, alle grün).
3. Gateway bereitstellen (eigener Strang): Repo-Stand mit `python/`, Konfiguration (`allowed_modes` zunächst nur
   `["shadow"]`), `state_dir`, Schlüsseldatei (≥ 32 Byte, Eigentümer `aria`, 0600). Prüfen ohne Plugin:
   `/usr/bin/python3 -I <REPO>/python/bin/aria_bridge.py --config <CFG> --status` → `key_available: true`.
4. Offline-Tests auf genau dem Stand, der eingespielt wird: `telegram/plugin/test/run-tests.sh` → alle grün.
5. Zeitpunkt mit Kais abstimmen: Während des Neustarts ist Telegram kurz taub; Telegram hält Updates bis zu 24 h vor
   und liefert sie nach dem Neustart aus [V: Bot-API-Dokumentation, nicht hier getestet].

## Schritt 1: Sicherung

```
cd /home/aria/.claude/plugins/cache/claude-plugins-official/telegram/0.0.6
cp -p server.ts server.ts.bak.$(date -u +%Y%m%d)-pre-v3
sha256sum server.ts server.ts.bak.*-pre-v3          # beide a20b9d6d…
cp -p ~/.claude/channels/telegram/.env ~/.claude/channels/telegram/.env.bak.$(date -u +%Y%m%d)-pre-v3   # nur falls Schritt 3 die .env ändert; Inhalt nie ausgeben
```

## Schritt 2: Einspielen (Reihenfolge ist wichtig)

1. **Zuerst** `aria-gateway.ts` neben `server.ts` legen. Grund: Fehlt das Modul, scheitert der Import von
   `server.ts` beim Start, und Telegram ist taub.
   `cp <REPO>/telegram/plugin/aria-gateway.ts ./aria-gateway.ts`
2. Dann `server.ts` ersetzen, entweder `cp <REPO>/telegram/plugin/server.ts ./server.ts` oder
   `patch -p1 --dry-run < <REPO>/telegram/plugin/server.ts.patch` und danach ohne `--dry-run`.
3. Prüfen: `sha256sum server.ts` = sha256 von `<REPO>/telegram/plugin/server.ts`; `grep -c aria-v3-gateway server.ts` = 2;
   `grep -c 'aria-patch: supabase log inbound' server.ts` = 1.
4. Keine neue Abhängigkeit: `aria-gateway.ts` importiert nur `node:`-Module; `bun install` beim Start bleibt unverändert.

## Schritt 3: Konfiguration, zunächst `off`

`ARIA_GATEWAY_MODE` nicht setzen oder `off`. Das ist exakt das Prod-Verhalten (Spurvergleich über 57 Szenarien,
`docs/TESTERGEBNISSE.md`). Später, für `shadow`, als eigene Zeilen ohne Anführungszeichen in die Umgebung des Plugins
(Ort: Entscheidung E34; Vorschlag `~/.claude/channels/telegram/.env`, weil `server.ts` sie dort lädt und
`wrapper.sh` unverändert bleibt):

```
ARIA_GATEWAY_MODE=shadow
ARIA_GATEWAY_BRIDGE=/abs/pfad/python/bin/aria_bridge.py
ARIA_GATEWAY_CONFIG=/abs/pfad/gateway.json
```

Achtung: Die `.env` gewinnt nur, wenn die Variable nicht schon in der Umgebung der Sitzung steht („Real env wins“).

## Schritt 4: Neustart

Neustart der Aria-Hauptsitzung (Kais/Admin, `aria.service`). Das alte `server.ts` endet über stdin-EOF bzw. wird über
die PID-Datei ersetzt; es entsteht kein zweiter Poller, weil weiterhin nur das Plugin pollt.

## Schritt 5: Prüfungen nach jedem Neustart

| # | Prüfung | Erwartung |
|---|---|---|
| 1 | `ps -eo pid,args \| grep 'bun server.ts'` und `/proc/<pid>/cwd` | genau ein Prozess, cwd = Plugin-Verzeichnis |
| 2 | Plugin-Log (stderr des MCP-Servers, Ort in Claude Code [V]) | einmal `polling as @…`, kein `409 Conflict` |
| 3 | Kais schreibt „Test“ | erscheint in der Sitzung, Antwort kommt |
| 4 | `/status` | `Paired as @…` |
| 5 | Berechtigungsdialog (ein Tool mit Rückfrage) | Buttons kommen, „Allow“ wirkt; Textantwort `yes xxxxx` wirkt |
| 6 | Foto und Dokument | `image_path` bzw. `attachment_file_id` kommen bei Claude an |
| 7 | Supabase `aria_chat_log` | neuer Eintrag `direction=in` |
| 8 | nur `shadow`: `decisions.jsonl` im `state_dir` | je Nachricht ein Datensatz mit echter `sender_id`/`chat_id`, `shadow: true`; Plugin-Log `aria-gateway: {…}` ohne Nachrichtentext |
| 9 | nur `shadow`: Antwortzeit | unverändert (Shadow wartet nicht) |

Schlägt 1–7 fehl: sofort `docs/ROLLBACK.md`.

## Schritt 6: Shadow-Beobachtung

Mehrere Tage `shadow`. Auswertung von `decisions.jsonl`: Verteilung `planned_handling`/`backend`, Fehlercodes,
Anteil `BRIDGE_BUSY`/`BRIDGE_TIMEOUT` im Plugin-Log, Datenschutzklassen. Erst danach über `active` entscheiden.

## Schritt 7: `active` (eigene Freigabe)

Voraussetzungen: E27 gelöst oder bewusst akzeptiert (Codex-Läufe blockieren sonst die Update-Schleife inkl.
Berechtigungsantworten), E5 bestätigt, Gateway-Konfiguration mit `allowed_modes: ["shadow", "execute"]`, Codex weiter
MockRunner bis E9. Setzen: `ARIA_GATEWAY_MODE=active` (optional `ARIA_GATEWAY_ON_FAILURE=block`), Neustart,
Prüfungen 1–7 plus: `/codex` → Bestätigung per Bot; `#public …` → Codex-Antwort (MockRunner); vertraulicher Text
im Codex-Modus → Sperre mit Erklärung; `/auto` zurück; Störung simulieren nur offline (Tests), nicht produktiv.

## Plugin-Updates

Jedes Update des Telegram-Plugins bringt ein neues Versionsverzeichnis ohne `aria-gateway.ts` und mit unveränderter
Upstream-`server.ts`. Die Sitzung läuft dann vermutlich mit dem Original weiter (Verhalten wie `off`, ohne
Supabase-Patch) [V: aus dem Verzeichnisaufbau geschlossen, kein Update beobachtet]. Nach jedem Update:
`grep -c aria-v3-gateway <neues-verzeichnis>/server.ts` (erwartet 2), sonst Patch gegen die neue Version neu bauen und
die Tests gegen die neue Prod-Kopie laufen lassen. Automatische Erkennung/Meldung: E26.
