doku: Historisches ins Archiv, Ueberfluessiges geloescht

- 19 Dateien nach docs/archiv/ mit Datumspraefix (JJJJ-MM-TT-): SAVEPOINT, Autonomie-,
  Optimierungs- und TTS-Plan, Review 02.07., ZeroClaw-Auftrag und -Ergebnis, Hermes-Setup,
  Gemini-Briefing, Antigravity-Review-Prompt, Zielbild, Uebergabe Drei Welten,
  Umbauplan Abloesung, Hermes-Werkzeuge, Raphael, die drei Dateien aus docs/aufgaben
  und der Skill-Text gitea-workflow.
- Die alte Liste OFFENE-FAEDEN (Stand 04.09.) ebenfalls ins Archiv; sie enthaelt die
  Lucy-Faeden, die sonst verloren gingen. Die neue Liste folgt im naechsten Schritt.
- Geloescht (kein eigenes Wissen, Git-Historie reicht): docs/memory/* (4 Kopien der
  Claude-Notizen vom Juni), STATUS, CUTOVER, AUDIT_KICKOFF, CLAUDE_CODE_BRIEF,
  UPGRADE und skills/orchestrator.md (Quelle war der Skill selbst).
- Formatfehler im Archiv behoben: uebrig gebliebene </content>-Tags im Optimierungsplan
  und im ZeroClaw-Auftrag; toter Link auf GEDAECHTNIS-BEREICHE.md zeigt jetzt auf die
  Git-Historie (geloescht am 07.08., c3851f8).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-09-24 15:31:00 +02:00
co-authored by Claude Opus 5.5
parent 4cd856bd34
commit 59631601b9
30 changed files with 1 additions and 799 deletions
+418
View File
@@ -0,0 +1,418 @@
# Umbau: OpenChamber als Coding-Bahn, Lucy bleibt SysAdmin
_Entschieden 21.08.2026. Rückbau der Hermes-Coding-Bahn ist **erledigt**, der Aufbau von
OpenChamber steht aus. Diese Datei ist die Übergabe an die nächste Sitzung._
## Die Entscheidung
**Zwei getrennte Bahnen** — der Weg, der bei diesem Stack schon einmal funktioniert hat:
| Bahn | Werkzeug | Zweck |
|---|---|---|
| **Betrieb** | Hermes-Runtime (Lucy) | SysAdmin, Telegram, Crons, Gedächtnis, Skills, Stimme, PC-Steuerung |
| **Coding** | **OpenChamber** über OpenCode | Nur programmieren. Getrennt von Lucy. |
| **Motor** | llama-swap `:8080` / MC2-Gateway `:9010` | beide Bahnen teilen sich die Modelle |
| **Steuerpult** | MC2 `:9001` | unverändert |
**Warum getrennt:** Der Versuch, beides in Hermes Desktop zu vereinen, ist an zwei Dingen
gescheitert — die Gateway-Registry akzeptiert kein Benutzer/Passwort (nur Session-Token oder
OAuth, beides für eine selbstgehostete Box ungeeignet), und der Sessions-Reiter fiel dadurch
immer auf „This device" zurück. Details in der Gedächtnisnotiz vom 20./21.08.
## Was bereits erledigt ist (21.08.)
**PC:**
- Hermes Desktop + CLI deinstalliert (`hermes uninstall --full`), Reste von Hand entfernt
- `AppData\Local\hermes`, `AppData\Roaming\Hermes`, `~\.hermes` — alle weg
- Startmenü- und Desktop-Verknüpfungen entfernt
- Env-Variablen bereinigt; **`HERMES_PC_TOKEN` bleibt bewusst** (Lucys PC-Executor auf `:7777`)
- Node v24.19.0 in `Program Files` ist unabhängig → bleibt, erfüllt OpenChambers Anforderung (≥22)
**Box:**
- Bot-Profile `coder` + `debugger` entfernt (gesichert in `~/archiv-aufraeumen-20260820/`)
- `~/.hermes/desktop-ssh/` entfernt, `desktop-auth.env` entfernt
- ufw: Port **9119 wieder zu** — nur noch `22 · 9001 · 8080 · 7681`
- Dashboard bleibt auf `0.0.0.0:9119` gebunden **mit Anmeldung**, damit MC2s `/hermes-ui`-Proxy
nicht mehr passwortlos aus dem LAN erreichbar ist (das war ein offenes Scheunentor).
Zugang: `~/.hermes/dashboard-login.txt` (0600), Benutzer `commander`.
‼️ Zugangsdaten stehen **nur** in `config.yaml` — die frühere `EnvironmentFile` hat sie still
überstimmt und kostete eine Fehlersuche. Eine Quelle, eine Wahrheit.
**Verifiziert nach dem Rückbau:** 5 Dienste aktiv · 4 MCP-Server · 4 Crons · Telegram `connected`
· PC-Executor HTTP 200. Lucy ist vollständig funktionsfähig.
## Was aufzubauen ist
### 1. OpenCode auf der Box
Wurde beim Juli-Rückbau entfernt (`command -v opencode` → leer). Muss neu.
```bash
# Installation (Box)
curl -fsSL https://opencode.ai/install | bash
# Provider auf den lokalen Motor zeigen lassen: ~/.config/opencode/opencode.json
# base_url http://127.0.0.1:9010/v1 (MC2-Gateway, kann model:auto)
# oder http://127.0.0.1:8080/v1 (llama-swap direkt)
# api_key local
```
Als systemd-**User**-Dienst (wie alle anderen — reboot-fest, sudo-frei):
```
opencode serve --hostname 0.0.0.0 --port 4096
```
Danach `ufw allow from 192.168.178.0/24 to any port 4096 proto tcp`.
### 2. OpenChamber auf dem PC
Desktop-Version von den GitHub-Releases (`openchamber/openchamber`, MIT, ~9,1k ★).
**Wichtig:** Die Desktop-Variante bringt eine eigene OpenCode-CLI mit — für den Remote-Betrieb
muss sie ausgeschaltet werden:
```
OPENCODE_HOST = http://192.168.178.151:4096 ← volle Adresse MIT Port, OHNE Pfad
OPENCODE_SKIP_START = true
```
> Fehlt der Port oder hängt ein Pfad dran, **ignoriert OpenChamber die Variable und startet
> stillschweigend seinen eigenen Server.** Genau diese Klasse Fehler hat uns bei Hermes einen
> halben Tag gekostet.
Modelle, Provider und Schlüssel liegen in **OpenCode**, nicht in OpenChamber.
### 3. Modellwahl — nicht wieder den dichten Coder
★★ **`fast` (Qwen3.6-35B-A3B) nehmen, nicht `coder` (Qwen3.8-27B).** Gemessen:
| | Ausgabe | Eingabe | SWE-bench Verified |
|---|---|---|---|
| `fast` Qwen3.6-35B-A3B (MoE) | **95,7 t/s** | 221 t/s | **73,4** |
| `coder` Qwen3.8-27B (dicht) | 12,6 t/s | 144 t/s | keine agentische Messung |
Das dichte Modell ist bandbreitenlimitiert (17 GB ÷ 215 GB/s ≈ 12,6 t/s = Hardware-Limit).
Der MoE ist **schneller und besser**.
### 4. Die Arbeitsanweisung mitnehmen — der wichtigste Fund überhaupt
Der Agent las in Lauf A eine ganze Nacht lang und schrieb **null Dateien**. Mit dieser Zeile
im Auftrag schrieb er in 24 Minuten fünf:
> **„Arbeite Datei für Datei. Lies HÖCHSTENS zwei Dateien, bevor du die erste änderst.
> Kein Gesamtplan, keine Vollinventur. Eine halbfertige Änderung ist wertvoller als eine
> vollständige Analyse ohne Änderung."**
Gehört in OpenChambers System-Prompt bzw. `AGENTS.md` der Projekte.
## Bekannte Fallen (aus dem Juli-Audit + heute)
- **Bus-Faktor 1** bei OpenChamber: ~70–80 % der Commits von einer Person. Version **pinnen**,
nicht blind auto-updaten.
- **Windows-Installer unsigniert** → SmartScreen-Warnung ist erwartbar, kein Alarm.
- Nie ohne `--ui-password` über localhost hinaus binden.
- `opencode web` (nicht OpenChamber!) hat einen kaputten Projekt-Finder für `$HOME` — falls
irgendwo ein leerer Projektbaum auftaucht, ist das der Grund.
- Git-Push zum Gitea geht vom PC **nur über PowerShell/GCM**, nicht aus der Git-Bash.
## Erster Test nach dem Aufbau
Die Referenzaufgabe liegt bereit und ist halb erledigt — ideal zum Vergleich:
```
Worktree: ~/projekte/mc2-referenz (Zweig referenz/mem0-ausbau)
Aufgabe: docs/aufgaben/referenzaufgabe-mem0-ausbau.md
Prüfung: bash docs/aufgaben/referenz-check.sh
Stand: 5 von 17 Dateien erledigt (Hermes-Lauf A2, abgebrochen durch SSH-Fehler)
```
Damit lässt sich direkt vergleichen: **Wie lange braucht OpenChamber + `fast` für dieselben
17 Dateien?** Hermes + dichter Coder brauchte hochgerechnet ~80 Minuten; die Rechnung für
`fast` sagt ~30.
---
## Stand nach dem Aufbau (21.08.2026)
**Beide Bahnen stehen. Der Aufbau ist erledigt, der Referenzlauf steht aus.**
### Box (`192.168.178.151`)
| Sache | Wert |
|---|---|
| OpenCode | **1.18.20**, `~/.opencode/bin/opencode` (eigenständiges Binary, kein Node nötig) |
| Dienst | `opencode-server.service` (systemd **user**, `enable`d, Linger=yes → reboot-fest) |
| Lauscht | `0.0.0.0:4096`, Arbeitsverzeichnis `~/projekte` |
| ufw | Regel 5: `4096/tcp ALLOW IN 192.168.178.0/24` |
| Provider | `box` → `http://127.0.0.1:9010/v1` (MC2-Gateway), `apiKey: local` |
| Modelle | `box/fast` (Standard) · `box/heavy` · `box/hermes` (small_model) · `box/coder` (nur Vergleich) |
| Autoupdate | `false` in `opencode.json` |
Konfiguration: `~/.config/opencode/opencode.json`.
**Nur Rollen-Aliase**, keine Modell-Eigennamen — die Konsolidierung wirft Eigennamen sonst raus (Regel vom 20.08.).
### Arbeitsanweisung — global verdrahtet
Liegt als `~/.config/opencode/ARBEITSANWEISUNG.md` und ist über `instructions` in
`opencode.json` in **jeder** Sitzung aktiv, nicht nur in Projekten mit `AGENTS.md`.
Gegengeprüft: „Wie viele Dateien höchstens?" → `2`. `~` wird von OpenCode expandiert.
### PC
| Sache | Wert |
|---|---|
| OpenChamber | **v1.19.0** (18.08.), `%LOCALAPPDATA%\Programs\@openchamberelectron` |
| Signatur | `NotSigned` — erwartet, kein Alarm |
| `OPENCODE_HOST` | `http://192.168.178.151:4096` (User-Env, mit Port, ohne Pfad) |
| `OPENCODE_SKIP_START` | `true` (User-Env) |
**Verifiziert:** OpenChamber hält 8 offene TCP-Verbindungen zur Box auf `:4096`,
startet **keinen** eigenen OpenCode (kein lokaler Prozess, kein lokaler Port).
Damit ist genau der Punkt genommen, an dem Hermes Desktop gescheitert ist.
**Auto-Update:** kein Riegel nötig. Im Bundle steht `autoUpdater.autoDownload = false` und
`autoInstallOnAppQuit = false` — OpenChamber lädt nie von selbst, es meldet nur und wartet
auf einen Klick. Die Version ist damit faktisch gepinnt.
### ‼️ Offene Sicherheitsentscheidung — bewusst so gewählt
Der Server läuft **ohne Anmeldung** im LAN. Beim Start meldet er selbst:
```
Warning: OPENCODE_SERVER_PASSWORD is not set; server is unsecured.
```
Praktisch heißt das: jedes Gerät im `192.168.178.0/24` kann über die API beliebige
Befehle als `hitonabi` auf der Box ausführen — dieselbe Klasse Loch wie das passwortlose
Dashboard auf `:9119`, das am 20.08. zugemacht wurde.
★★ **Ein Riegel wäre da und kostet nichts:** OpenChamber schickt HTTP-Basic-Auth mit, wenn
`OPENCODE_SERVER_PASSWORD` gesetzt ist (Benutzer aus `OPENCODE_SERVER_USERNAME`,
Standard `opencode`). Server-Variable in der systemd-Unit, gleiche Variable als User-Env
auf dem PC — **kein Tunnel, keine Umstellung, der Port bleibt offen im LAN.**
Der User hat am 21.08. **bewusst dagegen entschieden** („so lassen"). Nicht neu aufrollen,
aber hier notiert, damit es kein stiller Defekt bleibt.
### Nächster Schritt: der Referenzlauf
Alles steht bereit, nichts wurde am Prüfstand angefasst:
```
Worktree: ~/projekte/mc2-referenz (Zweig referenz/mem0-ausbau)
Stand: 5 von 17 Dateien erledigt, referenz-check.sh sagt ROT
Prüfung: bash docs/aufgaben/referenz-check.sh
```
Die Arbeitsanweisung wirkt dort über die **globale** Instruktion — `AGENTS.md` im Worktree
wurde absichtlich **nicht** angefasst, damit der Vergleich zu Lauf A/A2 sauber bleibt.
Zu messen: **Wie lange braucht OpenChamber + `fast` für dieselben 17 Dateien?**
Hermes + dichter `coder` brauchte hochgerechnet ~80 Minuten; die Rechnung für `fast` sagt ~30.
### ‼️ Falle: der Ordner-Knopf reicht Windows-Pfade an die Box durch
**Beim ersten Lauf sofort hineingetappt (21.08., ~1 h verloren).** Die Sitzung stand auf:
```
/home/hitonabi/projekte/F:\Coding Stuff\mission-control-2
```
OpenChamber hatte den **Windows-Pfad des PCs** an den Box-Server durchgereicht, der ihn hinten
an sein `WorkingDirectory` klebte. Das Verzeichnis existiert auf der Box nicht → der Agent hat
kein Arbeitsverzeichnis, es geht **keine einzige Anfrage** an den Motor raus. In der Oberfläche
sieht das aus wie „hängt": Nachricht steht da, eine Zusammenfassung erscheint, danach nichts.
`tokens: 0/0`.
**Ursache, im Bundle nachgesehen:** OpenChamber öffnet Ordner über Electrons natives
`showOpenDialog` — den **lokalen** Windows-Dateibrowser. Einen Fern-Auswähler gibt es nicht.
Im Fernbetrieb liefert dieser Knopf also *immer* einen unbrauchbaren Pfad.
**Der richtige Weg:** Seitenleiste → **„Projekt hinzufügen"**. Das ist ein eigener Dialog
(`directoryExplorerDialog`) mit Baum **und** Eingabefeld („Enter path or select from tree…"),
und der geht über den Server — also über die Box.
**Diagnose in einem Befehl** — wenn wieder „nichts passiert", zeigt das den Grund sofort:
```bash
ssh hitonabi@192.168.178.151 "curl -s http://127.0.0.1:4096/session | python3 -c \"import json,sys; s=json.load(sys.stdin); s.sort(key=lambda x: x['time']['updated'], reverse=True); x=s[0]; print(x['directory'], x.get('model'), x.get('tokens'))\""
```
Steht dort ein Pfad mit `F:\` oder `tokens 0/0`, ist es diese Falle.
**Merke:** Ein Projekt taucht in der Server-Liste erst auf, wenn dort einmal eine Sitzung lief.
`mc2-referenz` wurde am 21.08. mit einem harmlosen Lauf angemeldet (`box/hermes`, „Antworte nur
mit OK") — Worktree danach nachgemessen unverändert: 5 geänderte Dateien, HEAD `e04ace2`.
---
## ▶▶ Kurswechsel 21.08. (nachmittags): Quelle ist der PC, nicht die Box
Der Fernbetrieb oben war **falsch herum gedacht**. Der User arbeitet so — und so ist es
jetzt gebaut:
```
F:\Coding Stuff\… ← Quelle der Wahrheit, liegt IMMER lokal
│ OpenChamber startet seine EIGENE OpenCode-CLI und arbeitet an lokalen Dateien
│ git push (PowerShell/GCM)
▼
Gitea 192.168.178.153:3000
│ projekte-sync (stuendlich, --ff-only) — oder sofort per Skript
▼
AI-Box ~/projekte/… ← Spiegel fuer Deploy / CI / Lucy
▲
└─ von der Box kommt NUR noch das Modell (Inferenz ueber HTTP)
```
**Damit faellt die Windows-Pfad-Falle ersatzlos weg** — es gibt keine Fernpfade mehr.
### ★★ Kein Box-Umbau noetig: MC2 `:9001/v1` ist der Modellweg
Erst war geplant, den Gateway `:9010` ins LAN zu binden. Ueberfluessig — die Gateway-Unit
sagt es selbst: *„LAN-Clients kommen weiter ueber MC2 `:9001/v1`, das roh hierher
durchreicht."* Der Port ist seit jeher offen.
Vom PC aus gemessen: `:9001/v1/models` liefert **die Rollen-Aliase** (`fast`, `heavy`,
`hermes`, `coder`), `fast` antwortet in **0,7 s**. Kein neuer Port, keine Neubindung,
keine ufw-Regel — und **keine Modell-Eigennamen** in der PC-Konfiguration (die Regel vom
20.08. bleibt gewahrt). llama-swap `:8080` waere die Alternative gewesen, liefert aber nur
Eigennamen (`Qwen3.6-35B-A3B`) → genau der stille 404 vom 19.08.
### Was auf dem PC steht
`C:\Users\TobisPC\.config\opencode\opencode.json` — Provider `aibox` →
`http://192.168.178.151:9001/v1`, Standard `aibox/fast`, `small_model` `aibox/hermes`.
Die Juli-Struktur ist erhalten: Agenten `plan`(heavy) · `build`(fast) · `explore`(hermes) ·
`review`(heavy), inklusive **IDE-Zaun** (`ssh`/`scp`/`sftp` deny, gezielte Arcane-Ausnahme;
Catch-all `*: allow` steht ZUERST, weil OpenCode `findLast` auswertet).
Arbeitsanweisung als `ARBEITSANWEISUNG.md` daneben, ueber `instructions` global geladen.
Das Plugin `plugin/mc2-governor.ts` wird automatisch mitgeladen: Werkzeug-Zaun,
Pruef-Tor-Schleife, Savepoint statt Zusammenfassen, Meldungen an Lucys Stimme.
‼️ Es blockt **`git push`** absichtlich — *„Veroeffentlichen ist Sache des Menschen."*
Der Agent codet, gepusht wird von Hand (siehe Skript unten).
**Gebuendelte CLI:** OpenCode **1.18.18** in OpenChambers `resources\opencode-cli`.
Im lokalen Betrieb vergibt OpenChamber dem Server automatisch ein Passwort
(`OPENCODE_SERVER_PASSWORD`, lifecycle-owned) — `/config` antwortet von aussen mit `401`.
Der Schutz, den der Box-Server nicht hatte, ist hier also gratis dabei.
**Env-Variablen `OPENCODE_HOST` und `OPENCODE_SKIP_START` sind wieder ENTFERNT.**
Sie erzwingen den Fernbetrieb; mit ihnen startet OpenChamber keine eigene CLI.
### Box zurueckgebaut
`opencode-server.service` ist **gestoppt, deaktiviert und geloescht**, die ufw-Regel fuer
`4096` wieder entfernt. Damit erledigt sich die offene Sicherheitsfrage von heute Mittag
von selbst: der ungeschuetzte Dienst existiert nicht mehr. ufw steht wieder auf
`22 · 9001 · 8080 · 7681`.
### `deploy/push-und-sync.ps1` — der Handschlag
```powershell
.\deploy\push-und-sync.ps1 # committen -> pushen -> Box zieht sofort nach
.\deploy\push-und-sync.ps1 -NurSync # nur nachziehen
.\deploy\push-und-sync.ps1 -Pfad "F:\Coding Stuff\rippy"
```
Stoesst `projekte-sync` sofort an, statt bis zu 60 Minuten auf den Timer zu warten —
**kein zweiter Mechanismus, nur ein Ausloeser.** Meldet danach, auf welchem Commit die Box steht.
‼️ **Falle beim Bauen gefunden:** Der Repo-Name darf **nicht** aus dem Ordnernamen kommen —
lokal heisst es `mission-control-2`, in Gitea `mission-control-v2`. Das Skript liest ihn
aus der Remote-URL. Getestet gegen beide Faelle: MC2 (Live-Deployment, liegt als
Verknuepfung unter `~/projekte`) und `rippy` (normales Projekt, `a14449e`).
### Offener Punkt: PC-Remote haengt an der DDNS-Domain
Der PC pusht nach `https://git.tobisniceshomelab.ddnsfree.com/…`, die Box nutzt intern
`http://192.168.178.153:3000`. Die Domain ist nachts durch die Zwangstrennung zeitweise
tot (Lehre vom 24.07.). Umstellen mit:
```bash
git remote set-url origin http://192.168.178.153:3000/Hitonabi/mission-control-v2.git
```
Noch **nicht** gemacht — aendert Git-Konfiguration in den Repos des Users.
---
## Abschluss der Coding Lane (21.08.2026, abends)
### Der Zugang: ein SSH-Schluessel, kein Token mehr
**Der Ausloeser:** Mitten in der Sitzung scheiterte ein Push, der eine Stunde
vorher noch ging — `remote: Failed to authenticate user`. Der Git Credential
Manager haelt fuer Gitea ein **OAuth-Token mit einer Stunde Laufzeit**. Damit ist
HTTP fuer einen Agenten, der selbst pushen soll, strukturell ungeeignet.
**Was dabei herauskam:** Giteas SSH war **nie funktionsfaehig**. In der `app.ini`
stand zwar `DISABLE_SSH = false` und `SSH_PORT = 22`, aber im Container gibt es
**keinen `git`-Benutzer** und keine `authorized_keys` — Port 22 gehoert dem
System-sshd. Es sah nur so aus, als koennte man ueber SSH klonen.
**Loesung:** Giteas **eingebauten** SSH-Server eingeschaltet (Port 22 ist belegt,
deshalb 2222). Der verwaltet die Schluessel selbst, direkt aus der Datenbank —
kein `git`-Benutzer, keine `authorized_keys`.
```ini
# /etc/gitea/app.ini, [server] (Sicherung: app.ini.bak-20260821)
SSH_PORT = 2222
SSH_LISTEN_PORT = 2222
START_SSH_SERVER = true
SSH_LISTEN_HOST = 0.0.0.0
```
‼️‼️ **Der SSH-Benutzer heisst `gitea`, NICHT `git`.** Gitea laeuft unter diesem
Namen und weist alles andere ab. Die Fehlermeldung steht nur im Gitea-Log, nicht
beim Client — ssh sagt bloss `Permission denied (publickey)`:
```
Invalid SSH username git - must use gitea for all git operations via ssh
```
**Auf dem PC** (`~/.ssh/config`) — noetig, weil hier **acht** Schluessel liegen
und ssh sonst der Reihe nach durchprobiert, bis Gitea abbricht:
```
Host 192.168.178.153 gitea gitea.heimnetz
HostName 192.168.178.153
Port 2222
User gitea
IdentityFile ~/.ssh/id_general
IdentitiesOnly yes
```
Der Schluessel `id_general` ist in Gitea hinterlegt (Nr. 3) — **derselbe, mit dem
du auf Box, pve und Arcane kommst.** Von acht Zugangsdaten auf einen.
Alle sieben PC-Repos stehen jetzt auf
`ssh://gitea@192.168.178.153:2222/Hitonabi/<repo>.git`.
Das TTT2-Projekt bleibt unberuehrt — es haengt an einer anderen Domain und ist
als „Finished" markiert.
### Gemessen, nicht angenommen
| Test | Ergebnis |
|---|---|
| `ssh -T gitea` | „Hi there, Hitonabi! You've successfully authenticated with the key named id_general" |
| Push aus PowerShell | 8 Commits, `7c23ebf..25dbfb2` |
| **Push aus dem Agenten** | durchgelaufen, **keine Passwortabfrage** |
| Erzwungener Push aus dem Agenten | vom Werkzeug-Zaun abgewiesen |
| `push-und-sync.ps1` komplett | Commit → Push → Box zieht nach |
### Der Sonderfall MC2
`projekte-sync` zieht `mission-control-v2` **absichtlich nicht** — die Box
bedient daraus den laufenden Dienst auf `:9001`. Nach einem Push steht dort
weiter der alte Commit, und das ist richtig so. Das Live-Deployment braucht
seinen eigenen, bewussten Schritt. Alle anderen Projekte werden normal gezogen.
### Fallen fuer das naechste Mal
- **`sed` mit `$` und `\n` ueber PowerShell zerlegt sich.** Der erste Anlauf,
die `app.ini` zu aendern, lief ins Leere und die Datei blieb unveraendert —
ohne Fehlermeldung. In einzelne Ersetzungen zerlegen und **danach nachsehen**.
- Ein Dienst-Neustart nach einer Konfig-Aenderung ist noch keine Bestaetigung:
Gitea startete brav neu — mit der alten Datei.
- Acht SSH-Schluessel auf dem PC sind selbst ein Befund. `IdentitiesOnly yes`
ist Pflicht, sonst bricht die Gegenseite vorher ab.