Files
bf-infra/docs/handoff-20260827-inventur-und-architektur.md
Christoph Emsenhuber dd12ab505b Korrektur: bf-infra HAT ein Gitea-Remote (Inventur-Aussage vom 08-27 ueberholt)
CLAUDE.md behauptete "lokal, kein Gitea-Remote (Working-Copy). Verloren bei
Festplattencrash." Live geprueft 2026-08-30:
  origin = https://gitea.emsenhuber.net/admin/bf-infra.git
  origin/main = b917691 (Handoff 2026-08-28)
Das Remote existiert also seit spaetestens 2026-08-28. Die Aussage war bei
der Inventur am 08-27 richtig und ist seither ueberholt -- nicht falsch
erhoben, sondern nicht mitgezogen.

Anlass: eine Session hat die Zeile uebernommen und "lokaler Master ohne
Gitea-Remote" behauptet, statt `git remote -v` zu tippen. Genau der Fall aus
dem Lessons-Block "Kommentar in Code != Verhalten". Merkregel deshalb an der
korrigierten Zeile verankert.

CLAUDE.md: Zeile direkt korrigiert (lebende Anweisungsdatei).
Handoff 2026-08-27: Originalzeile bewusst erhalten, Korrekturvermerk
darunter -- historische Fassungen werden hier nicht umgeschrieben.

Die Backup-Luecke bleibt real, hat aber eine andere Ursache als notiert:
nicht fehlende Struktur, sondern ungepushte Commits (am 08-30 waren es vier).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-30 11:43:24 +02:00

132 lines
8.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handoff 2026-08-27 — Inventur + Asymmetrie + Architektur-Vorschlag
> Bezug: TP34 (Caddyfile via Nautobot/GC, neu, Stub-Eintrag in `docs/teilprojekte.md`).
> Inventur-Session mit Christoph, alles Read-Only geprüft (CF-API live, MikroMCP-ARP live,
> Gitea-REST live).
## TL;DR
- `bf-infra` ist **aktiver Fork** von `bf-network-r6`; aktiv gepflegt, **kein Gitea-Remote** → Backup-Lücke.
- 🔴 **Korrektur 2026-08-30 (Befund steht, Schlussfolgerung überholt):** das Remote existiert inzwischen — `origin` = `https://gitea.emsenhuber.net/admin/bf-infra.git`, `origin/main` = `b917691` (2026-08-28). Der Satz oben war am 08-27 zutreffend und ist **bewusst erhalten**; er darf aber nicht mehr als Ist gelesen werden. Die Backup-Lücke schließt ein `git push`, kein neues Repo.
- `admin/bf-network-r6` (Gitea) = historischer Master, letzte aktive Commits 2026-08-25 → auf read-only stellen (deine Aktion).
- `admin/bf-golden-config` (Gitea) = Bot-Master (Nautobot BACKUP/GENERATE 2×/Tag) → kein lokaler Mirror.
- `admin/blaueblueten-n8n` (Gitea) = Master für terpene-Repo, aktiv.
- Inventar-Pipeline gelöscht (XLSX stale seit 2025-06-05, vor Core-Cutover; Live-Daten via MikroMCP/CF/Portainer).
- Architektur-Vorschlag: **Caddyfile als Generated aus Nautobot/GC**, nicht handgeschrieben (TP34).
## Drift-Befund (Phase 0)
| # | Quelle A | Quelle B | Konflikt | Einschätzung „wahrscheinlich richtig" |
|---|---|---|---|---|
| **D1** | `inventory/bf.csv`/`bf.md` (219× `10.40.41.x`) | CLAUDE.md / teilprojekte.md (`10.40.20.x`) | Inventar führt altes VLAN1-Subnetz | Inventar war tot; **gelöscht**. CLAUDE.md ist richtig. |
| **D2** | Caddyfile → `10.40.20.167:5678` | Mac mini ARP-reachable | Konsistent | Caddyfile ist richtig, Tunnel ist nur Ingress für CF-CNAMEs. |
| **D3** | `cf-tunnel-mapping.md` §15-Tabelle: `terpene-db` 1 Connector | Live CF-API: `terpene-db` 4 Connectoren | Doku-Drift | Live ist richtig, Doku-Stand 08-25. |
| **D4** | `STATUS.md` Z.47: „Ingress `terpene.teilzeitladen.xyz` → `macmini:8890`" | Live: kein Tunnel hat diesen Hostname | Doku-Lüge | STATUS.md ist veraltet; **kein CNAME, kein Ingress**. Worker läuft nur über CF-Workers-Custom-Domain `420.teilzeitladen.xyz`. |
| **D5** | `~/.claude.json` enthält `terpene-pg` MCP | `pg_hba.conf` blockiert `10.40.10.0/24` | Geistereintrag | MCP konfiguriert, scheitert aber. Entscheidung offen (Fix oder Austragen). |
| **D6** | `~/.claude.json` 9 MCPs vs. `mcp/INVENTORY.md` 4 | Unterschiedlicher Scope | Beide richtig | `~/.claude.json` = globaler Werkzeugkasten, INVENTORY = BF-Netz-SSoT. Keine Synchronisation nötig, Notiz reicht. |
| **D7** | `memory/project_tp2_topology.md` | TP2 RETIRED (Omada) | Tote Memory-Datei | **Gelöscht** (im selben Commit mit Inventar). |
| **D8** | `handoff.md` im Root | Konvention: `docs/handoff-YYYYMMDD-thema.md` | Konventionsbruch | **Verschoben** zu `docs/handoff-20260827-hubert-und-altlasten.md`. |
| **D9** | `cf-tunnel-mapping.md` §10: `bf-nas = 70d6a4cf` | Live: `bf-nas = 220c9958` | §10 stale, §15-Nachtrag korrigiert | §15 hat es; §10 nicht. Kosmetik. |
| **D10** | Gitea `bf-network-r6/docs/cf-tunnel-mapping.md` | Lokal `~/dev/bf-infra/docs/cf-tunnel-mapping.md` | Gitea ist 1 Comm voraus, lokal ist Import-Stand | Gitea ist Master; Lokal ist veraltet (kein Sync). |
## Veraltet / tot (bereits aufgelöst)
| # | Was | Aktion |
|---|---|---|
| T1 | `inventory/bf.csv`, `bf.md`, `IPs.xlsx`, `build.py`, `bf-core-ports.*` | gelöscht (Commit 1) |
| T2 | `memory/project_tp2_topology.md` | gelöscht |
| T3 | `handoff.md` im Root | verschoben nach `docs/handoff-20260827-…` |
| T4 | `STATUS.md` Z.47 (Mac-mini-Ingress) | offen, manuelle Edit (nächste terpene-Session) |
| T5 | `bf-public` Tunnel (inactive, 0 Connector) | bewusst aufgehoben, Teil von TP31 Schritt 5/6 |
## Asymmetrie (Repo-Struktur)
| Repo | Lokal? | Gitea? | Master? |
|---|---|---|---|
| `bf-infra` | ✅ Working-Copy | ❌ kein Remote | **lokal** (Sicherheitsrisiko) |
| `bf-network-r6` | ✅ Mirror | ✅ Master (read-only geplant) | Gitea |
| `bf-golden-config` | ❌ kein Mirror | ✅ Master (Nautobot-Bot) | Gitea |
| `blaueblueten-n8n` | ✅ Mirror | ✅ Master | Gitea + lokal synchron |
**Dringlichkeit:** `bf-infra` ohne Remote = alle Edits nur lokal, kein Backup. **Festplattencrash = Datenverlust.**
## Inventar-Entscheidung
- Pipeline war seit **2025-06-05** tot: `IPs.xlsx` (Quelle) ist nicht aktualisiert, `build.py` rendert nur.
- Inventar ist seit Core-Cutover (2026-08-08) **inhaltlich falsch** (alle IPs `10.40.41.x`).
- Live-Daten kommen jetzt aus **MikroMCP** (ARP/DHCP/Interface je Router), **CF-API** (Tunnel/Ingress), **pve-mcp** (VM/LXC), **Portainer/Komodo** (Container).
- **Entscheidung: Inventar-Datei löschen.** Live-Tooling deckt den Bedarf.
## Architektur-Vorschlag (TP34 — Caddyfile via Nautobot/GC)
### Warum
Heute ist der Caddyfile (16 Sites, `bf-infra/caddy/Caddyfile`) **manuell gepflegt**. Problem:
- **Manuelle Edits** erlauben Drift.
- **Keine generische Schnittstelle**: andere Projekte (terpene, blaueblueten-n8n) können keine Sites anlegen, ohne Christoph zu fragen.
- **Kein Compliance-Check**: ein fehlerhafter Block bleibt stehen, bis jemand manuell vergleicht.
- **Keine Transaktionen**: ein kaputter Eintrag bricht die ganze Datei.
### Zielbild
Caddyfile wird **generated** aus einem **Nautobot-Datenmodell** + **Golden Config Pipeline**, identisch zum bestehenden Workflow für Router-Configs.
### Datenmodell (Skizze)
Nautobot-Entities:
- **Site**: `bf`, `fm`, `dw` (Standort, gehört zu ggf. `cf-public` Catch-all)
- **Host**: `vw.bf.emsenhuber.net` — mit Attributen `site`, `public` (boolean), `access_policy` (optional)
- **Backend**: `10.40.20.127` (Vaultwarden) — mit Attributen `protocol` (http/https), `tls_insecure` (bool), `host_header` (optional)
- **SiteBinding**: Host ↔ Backend (m:n, falls mehrere Backends pro Host)
### GC-Workflow (Skizze)
1. **Generate**: Golden Config rendert aus Nautobot-Daten den Caddyfile.
2. **Diff**: gegen die Live-Version auf `caddy-bf1` (Caddy-Admin-API `:2019/config/`).
3. **Compliance**: Pflichtfelder (jeder Host braucht Backend, jeder Backend braucht Protokoll), keine hardcoded IPs in Caddyfile, keine `tls_insecure_skip_verify` ohne Annotation.
4. **Transaktion**: Snapshot vor Deploy, Rollback bei Fehler.
### Erster Anwendungsfall: terpene.teilzeitladen.xyz
- Backend: `http://10.40.20.167:8890` (Mac mini, Caddy dort bedient PostgREST + sync + web)
- Access: CF-Access mit Service-Token `terpene-verify-v2`
- **Vorteil**: terpene-Caddyfile-Block wird in 30 Sekunden via `nautobot/gc-configplan.py` deployed, mit Diff und Rollback. Backfill-SQL ist dann via `admin/migrate` callbar.
### Abhängigkeiten
- **TP22** (Golden Config Pipeline) ✅ vorhanden
- **TP23** (DNS-Policy + Caddy-Schnittstelle-Voraussetzungen) ✅ Stufe 1
- Hängt an **nichts** außer der Implementierung.
### Status
🔜 Stub. Implementierung in eigenem Runbook, nach terpene-Caddy-Block (Quick-Win).
## Übergangsplan bf-network-r6 → bf-infra
| Schritt | Wer | Wann |
|---|---|---|
| bf-infra lokal Master (dieser Commit) | ich | ✅ |
| bf-network-r6 im Gitea: read-only + Header mit Verweis | du | offen |
| bf-infra bekommt Gitea-Remote (`admin/bf-infra` neu) | offen, „später" | nach terpene-Caddy-Block |
| Caddyfile-Master wandert zu Nautobot/GC (TP34) | nach terpene | nach Quick-Win |
## Offene Punkte (für nächste Session)
- **terpene-Caddy-Block** (zeitkritisch): Quick-Win vor TP34, manueller Eintrag in `bf-infra/caddy/Caddyfile` für `terpene.teilzeitladen.xyz → http://10.40.20.167:8890`. Mit Commit-Kommentar, dass das nicht das Pattern ist.
- **`STATUS.md` Z.47** korrigieren: Streichen oder Realität einarbeiten.
- **`~/.claude.json` `terpene-pg`**: deine Aktion (pg_hba-Erweiterung oder austragen).
- **TP34 Implementierung**: Runbook + Nautobot-Datenmodell-Skizze, sobald terpene-Caddy-Block committed ist.
## Selbstkritik / Lessons Learned für Sessions
- **Bestandsaufnahme vor Plan.** Erst was ist da, wo ist der Schaden — dann Vorschläge. Nicht umgekehrt.
- **Eine große Fragenrunde statt vieler kleiner.** Wenn der Plan von Annahmen abhängt, sammle die Annahmen in einer Runde, nicht in 3–4 Mikrorunden.
- **Master-Frage früh stellen.** Bei jedem Repo, jeder Datei, jedem Tooling: „Was ist die SSoT, wo lebt der Master, was ist Mirror?" — bevor du eine Lösung vorschlägst.
- **Drift zuerst, Lösungen später.** Drift-Tabelle posten + fragen, was richtig ist. Keine Lösungen vor dem Befund.
## Stand
- 2026-08-27
- Inventur-Session mit Christoph
- Commits: `8d2b4a7` (Aufräumen) + dieser Handoff-Commit