Commit Graph

429 Commits

Author SHA1 Message Date
bd1ba5ed13 TP35 Schicht 3: globale Verhaltensregeln konsolidiert (AGENTS.md SSoT + CLAUDE.md Spiegel) 2026-08-29 18:55:12 +02:00
f1a8a4a3e7 TP35 Schicht 1: MCP-Migration FQDN→IP (gitea-mcp .167:3000, n8n-mcp .167:3001) + Ist-Stand/Quick-Index nachgezogen 2026-08-29 18:42:33 +02:00
b9176914e2 Handoff 2026-08-28 (Abends): terpene W1-W7 + globale MCP-Migration + CF-Token-Diagnose
Christophs Kontext explodiert am Sessionende. Handoff bündelt:
- CF-Token-Audit-Befund: CF_DNS_API_TOKEN ungültig (Code 1000 'Invalid API Token'),
  Christophs Verdacht 'falscher Token extrahiert' bestätigt.
- Globale MCP-Migration FQDN → IP für gitea-mcp + n8n-mcp; cloudflare bleibt
  extern (User-Direktive explizit). WARP-Pfad statt Bearer-Header wenn der
  Connector intern ohne Token lebt.
- terpene W5: n8n-mcp in blaueblueten-n8n/.mcp.json (User-Zustimmung).
- Domain-Korrektur: 420.teilzeitladen.xyz ist die echte terpene-Domain
  (NICHT terpene.teilzeitladen.xyz) — User-Direktive, gilt für alle.
- W1/W6 bleiben User-blocked, W7 wartet auf TP31-Schritt 5/6.

Dringend beim Nachfolger: CF-Token-Validität zuerst klären, dann erst
MCP-Migration. STATUS.md im terpene-Repo ist auf die falsche Domain
korrigieren.
2026-08-28 23:51:46 +02:00
733d911c03 shelly-mcp in opencode.jsonc registriert (remote MCP gegen DS923 .180:3030)
Container shelly-mcp läuft seit dem mcp<2-Pin-Fix auf DS923 (10.40.20.180,
macvlan vlan20). Eintrag in der projekt-spezifischen Config analog zu pve-mcp:
type=remote, kein Bearer (Container nimmt keine Auth entgegen, lebt im
BF-LAN hinter deny-by-default — s. TP5).

Abnahme: mcp list 11/11, shelly-mcp connected, /health antwortet
200 mit psk_configured:true.
2026-08-28 21:31:54 +02:00
b8fd42b3fd shelly-mcp: mcp<2 pinnen + TP30 Posten #3 hochstufen
Container crashte beim ersten Deploy mit 'No module named mcp.server.fastmcp':
PyPI hat mcp 2.x als aktuellste Version, FastMCP wurde dort zu MCPServer
umbenannt. Repo-Code (server.py) nutzt noch v1-API.

Fix: requirements.txt 'mcp[cli]>=1.0,<2' — hält den Server auf v1-kompatibel.

Deploy-Ergebnis:
- Container shelly-mcp auf DS923, IP 10.40.20.180 (macvlan vlan20)
- Health /health: 200, psk_configured:true, iot_ssid=dirtyvader-iot
- StreamableHTTP /mcp: serverInfo 'shelly-mcp 1.29.1'
- Live-Sweep 10.40.30.180-250: 23 Shellys erreichbar

TP30 Posten #3 (Shelly-Gerätepasswort) hochgestuft: SHELLY_DEVICE_PW ist im
Zuge dieses Deploys erneut in ein Sitzungstranskript geraten (sed-Pattern
'SHELLY_DEVICE_PW=.*' hat den Wert nicht maskiert, weil der Replacement-
String zu wenig greedy war — neuer Lessons-Block-Eintrag). Reihenfolge:
erst Werkzeug-Härtung (Stream-Filter statt cat+sed), dann Posten #3
rotieren. CLAUDE.md hat den Lessons-Eintrag, TP30 Posten #3 hat die
Hochstufungs-Begründung.
2026-08-28 21:27:05 +02:00
3562e19e47 Portainer 2.40 → 2.42.0 Bump + portainer-mcp projektspezifisch
Portainer-Server (pve LXC 400): 2.40.0 → 2.42.0 via Image-Swap mit Volume-Erhalt.
Pre-Upgrade-Snapshot: docker commit :2.40.0-preupgrade-20260828 (Rollback 7 d
verfügbar) + Settings/Stacks/Endpoints-JSON-Dump (40 KB, 31 Stacks, 4 Endpoints).
Instance-ID + API-Token nach Bump identisch — kein Re-Auth, kein Settings-Verlust.

portainer-mcp: offizielles PyPI-Paket mcp-portainer~=2.42.0 (193 Tools), nur
in bf-infra/opencode.jsonc, via uvx-stdio. Tool-Gate: get_guidance() einmal pro
Session zwingend vor erstem Read. Andere Projekte unberührt.

Korrekturen ggü. Handoff 2026-08-28 README:
- mcp-portainer PyPI bis 2.42.6, Docker-Hub portainer/portainer-ce nur bis 2.42.0
  (unterschiedliche Versionierungspfade).
- mcp/portainer/README.md ist auf 2.42.6 formuliert und sollte nachgezogen werden.

Bestand: mcp/INVENTORY.md portainer-mcp ⛔→🟢 + Header MCP-WARP-Direktive ergänzt.
.mcp.json (war getrackt aus Commit 3426366) entfernt: opencode nutzt opencode.jsonc,
nicht .mcp.json — Claude-Code-Konvention hier irrelevant.
2026-08-28 21:17:52 +02:00
c25888acd9 Lessons: Skills sind IMMER global, niemals pro Projekt 2026-08-28 19:47:30 +02:00
b4cd417e8d Lessons: opencode-TUI-Leading-Space als bekannter Bug dokumentiert (Issue #27528, status 'Not planned') 2026-08-28 19:30:35 +02:00
55b3453d41 Lessons-Checkliste: Output-Länge als Regel 6 ergänzt 2026-08-28 19:27:21 +02:00
d06d505bc3 TP36 angelegt + Ist-Stand-Block aktualisiert + zwei Lessons-Eintraege
Befund 2026-08-28 nach Skill-Verifikation in opencode:
- Der 'Nächster Schritt (2026-08-26)'-Absatz war zwei Tage veraltet
  (drei Sessions waren parallel offen)
- Manuelle Doku mit Live-Daten verliert gegen die Realitaet, sobald
  die Datei lang wird (1940 Zeilen, drei Stellen pro Edit)

Reaktion:
1. 'Nächster Schritt' umgeschrieben: drei Folge-Sessions A/B/C aus
   dem gestrigen Handoff, klar als 'parallel' markiert. A ist erledigt
   (TP35 Schicht 6), B+C offen.
2. TP36 als Folge-TP neu angelegt: SSoT via Nautobot fuer
   teilprojekte-Live-Daten + Datei-Aufteilung (Index / Snapshot /
   Archiv). Eigene Session, nicht heute.
3. CLAUDE.md: zwei Lessons-Eintraege:
   a) opencode-TUI: fuehrendes Leerzeichen vor /command manchmal
      noetig (Beobachtung, kein Skill-Bug)
   b) Manuell gepflegte Doku verliert gegen Realitaet, Merkregel:
      drei Stellen pro Edit mitlesen (Quick-Index, TP-Abschnitt,
      Ist-Stand); strukturelle Antwort = TP36

Lessons-Block hat jetzt 7 Eintaege (Stand 2026-08-28).
2026-08-28 19:23:28 +02:00
8c1876c1d6 TP35 Schicht 6: /projektstatus-Skill in opencode aktiviert + Doku
- CLAUDE.md: zwei Lessons-Eintraege (opencode-Default-Pfad kopieren,
  nicht symlinken; Kommentar in Code != Verhalten)
- teilprojekte.md: TP35 Quick-Index auf 'Schicht 6 erledigt, Rest offen',
  Schicht-6-Befund im TP-Block, Ist-Stand auf 2026-08-28 mit MCP-Bestand-
  Korrektur
- handoff-20260828-session-a-projektstatus.md: Session-A-Bericht mit
  Drift, Befund, Entscheid, Lehren fuer Session B

Skill selbst liegt in ~/.config/opencode/skills/projektstatus/SKILL.md
(cp aus ~/.claude/skills/projektstatus/, byte-identisch) - opencode
scannt diesen Default-Pfad, kein skills.paths-Eintrag in der JSONC
noetig.
2026-08-28 19:15:02 +02:00
433e600f83 TP16.3 cloudflared: Config + Bootstrap + .gitignore fuer Tunnel-Secret
cloudflared-Konfigurationsmaterialien fuer TP16.3 (BFF-public-Tunnel
auf dem Edge statt cloudflared-QUIC-Workaround). Enthaelt:

- ap-bootstrap.rsc: RouterOS-Script fuer ap1/ap2 (veth, srcnat,
  container-mounts, env-Vars). Token kommt aus ~/.secrets, wird per
  SFTP auf den Router kopiert — kein Klartext im Script.
- cloudflared-bf-public-config.yml: tunnel-UUID + credentials-Pfad
  (KEIN Secret). Ingress wird CF-Dashboard-gemanagt (config_src=cloudflare).
- .gitignore: credentials.json mit dem Tunnel-Secretbase64
  (PrivateKey des Tunnels, niemals committen).

Status: vorbereitet, nicht ausgefuehrt. credentials.json bleibt lokal.
2026-08-28 19:09:10 +02:00
840d57bca3 TP31 Schritt 5: cloudflared-Runbook ap1/ap2 + CNAME-Flip
Vorbereitetes Runbook für TP31.5 (cloudflared-Container auf hAPs statt
TUN-Device-Workaround, da WARP-Connector auf ROS nicht möglich). Inhalt:

- Image-Build (RouterOS 7.x container, 70 MB Budget je AP)
- Pro AP: veth, interface-list-Mitgliedschaft, container-env
- CNAME-Flip von CF-Tunnel auf ap1/ap2 (DNS-Propagation, Rollback)
- Voraussetzungen: WAN-Healthcheck, Tunnel-Secret aus credentials.json
  (siehe routeros/cloudflared/.gitignore im Folge-Commit)

Status: vorbereitet, nicht ausgeführt. Stand 2026-08-27.
2026-08-28 19:08:51 +02:00
27863c1f2e shelly-mcp: Build-Materialien (Dockerfile + Anleitung)
Vorbereitung für Session B (Deploy auf DS923). Datei-Set reicht für
Image-Build ohne weitere Quellen aus dem Repo:

- Dockerfile: python:3.12-slim, mountbares /config ohne .env-COPY
- requirements.txt: mcp[cli]>=1.0, starlette>=0.36 (StreamableHTTP)
- BUILD.md: rsync → docker build → Portainer-Container-Deploy
- .gitignore: .env (Schema-Vorlage lokal) + __pycache__ ausklammern

Die Live-Instanz .env und der Container selbst werden in Session B
gebaut, nicht hier. Kein Secret in Git.
2026-08-28 19:08:43 +02:00
759491b512 MCP-Bestand korrigiert + Mac-mini-Performance-Restriktion
- gitea-mcp + n8n-mcp nachgetragen (waren real live, aber aus dem Inventar verschollen)
- pve-mcp: SSE-Doku -> StreamableHTTP-Realitaet
- shelly-mcp/portainer-mcp: bewusst KEIN MCP-Client (User-Direktive 2026-08-28)
- Mac mini = n8n-Host, NICHT zentraler MCP-Host (Performance-Restriktion)
- ~/.claude.json + opencode.jsonc: 9 MCPs identisch (vorher 7 vs. 11 Asymmetrie)
- docs/mcp-host-policy.md: SSoT fuer Host->FQDN/Stack-Mapping
- docs/handoff-20260828-mcp-bestand-und-performance.md: Folge-Sessions A/B/C

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-28 18:40:05 +02:00
claude-code
dc38d821c2 session-briefing-20260828.md: TL;DR + Lese-Reihenfolge für neue Sessions
Eine Seite, die eine frische Session in 30 Sekunden auf Stand bringt:
TL;DR, Lese-Reihenfolge (Handoff → Anker → TP35), sofort-tun-Liste,
Übergabe-Mechanik, Mid-Action-Checkpoint, Commit-Hinweis-Regel, Was-offen.

Löst das 'Bahnhof'-Problem, das Christoph beim Session-Neustart
beobachtet hat.
2026-08-28 17:33:23 +02:00
claude-code
5797364e4d drift-korrektur: Auth-Sanierung (Bearer) gehört in TP16.3, nicht als Vorab-Notiz
TP16.3 existiert seit 2026-08-17 (Quick-Index Z. 194, Body Z. 401,
Runbook tp16.3-nautobot-mesh-only-runbook.md) und deckt 'alle Tools
über Caddy oder CF + Caddy (extern)' + Auth-Sanierung bereits ab.

Mein Fehler: ich habe im Index nicht nachgeschaut und einen Vorab-Punkt
formuliert, der TP16.3 doppelt. Anwender hat das in dieser Session
explizit markiert ('das darf dir kein 2. mal passieren').

Fix:
- Session-Anker: Vorab-Notiz entfernt, ersetzt durch Verweis auf TP16.3.
- TP16.3-Body: technische Notiz 'n8n-mcp Accept-Header-Strike +
  Auth-Sanierung' eingepflegt (SSE-Header-Konsequenz für künftiges
  Caddy-Fronting, Reihenfolge TP16.3 → TP35 Schicht 2).

Lehre: vor jeder Aussage 'gibt's noch nicht' oder 'neuer TP nötig':
erst grep auf den Quick-Index in teilprojekte.md.
2026-08-28 17:18:16 +02:00
claude-code
a2465b8586 session-anker: Auth-Sanierung (Bearer) als Vorab-Notiz für Cloudflare-Tunnel-Punkt
n8n-mcp-Accept-Header-Strike wird mit dem noch kommenden CF-Tunnel-Punkt
gelöst, nicht heute. Bearer-Authentifizierung soll einmal sauber per
Caddy/CF-Access zentralisiert werden — TP35-Schicht-2 Endform hängt davon.

Inhalt: nur Doku, keine Migration, kein neuer TP, keine Config-Änderung.
2026-08-28 17:14:16 +02:00
claude-code
8ad355e059 session-anker: n8n-mcp failed = Accept-Header-Strike (406), nicht Token-Fehler
Diagnose: n8n-mcp verlangt 'Accept: application/json, text/event-stream'
(StreamableHTTP-Modus). opencode mcp list schickt nur 'application/json',
kriegt 406, wertet als failed. Echter Tool-Aufruf nutzt richtigen Header,
deshalb Sidebar grün. Bearer-Token + Server sind gesund (200 OK mit
richtigem Accept-Header, serverInfo: n8n-documentation-mcp 2.57.1).

Konsequenz: 'failed' in mcp list ist nicht 'kaputt' sondern 'Probing-Header
zu strikt'. Sidebar-Status bleibt Wahrheit.
2026-08-28 17:11:47 +02:00
claude-code
d711625d29 session-anker: MCP-Status-Check Cold-Start-Race notiert (n8n-mcp verified) 2026-08-28 17:07:10 +02:00
claude-code
389b146a91 tp35 angelegt + session-anker: MCP-Schichtung global/projekt/user
TP35 = Konzept + Schichtung, nicht die Umsetzung. Ausarbeitung
in eigener Session pro Projekt mit eigenem Handover-Post.

Scope (6 Schichten):
1. MCP-Schichtung global/projekt/user
2. Credentials-Schichtung (alle Secrets in ~/.secrets/exports.zsh)
3. 3-Schicht-CLAUDE.md (öffentlich/gitignored/global)
4. Announcement-Mechanismus (Hybrid)
5. Backup-Guard (3 Tage aktiv, 5 Commits oder 1000 LOC diff)
6. /projektstatus-Skill global (als Erstes)

Begleitend: docs/session-20260828-decisions.md = Mini-Anker mit
F1-F5-Begründungen + 3 Korrekturen unterwegs (Ollama 2 Hosts,
uwe-job-bewerbung doch dabei, Backup-Guard = aktive Tage).

Backups: 12/12 gzip-valid in ~/dev/.pre-opencode-migration-backups/20260828-150335/
2026-08-28 17:04:33 +02:00
claude-code
799e3efaee handoff: pre-opencode-migration, backups done, plan open, mid-action correction received 2026-08-28 15:18:06 +02:00
7e81ce6a36 handoff: 2026-08-28 — MCP-Cleanup, shelly-mcp-Tote, nächste Schritte
- Neue Handoff-Datei für den konkreten nächsten Schritt (im Gegensatz zur
  Inventur-Handoff, die den Master-Plan zeigt).
- Dokumentiert: cannaleo/terpene-pg entfernt, n8n-mcp repariert,
  shelly-mcp-Tote entdeckt, CLAUDE.md-Erweiterung.
- Liste der offenen Aktionen für die nächste Session: bf-network-r6
  archivieren, terpene-Caddyfile-Block, STATUS.md Z.47 korrigieren,
  n8n-mcp auch in ~/.claude.json, gitea-mcp-Init-Problem.
2026-08-28 14:40:08 +02:00
046f103a89 claude.md + handoff: shelly-mcp-Tote erkannt, MCP-Lifecycle-Regeln
- shelly-mcp läuft auf keinem Host (kein Mac-Prozess, kein Container auf
  NAS/pve). INVENTORY-Handoff hatte den Stand nicht aktualisiert.
  Config jetzt enabled=false, neuer Punkt im Ist-Stand-Block.
- 3 neue Lessons-for-Sessions-Regeln: MCP-Änderungen aktiv melden,
  Host vor Edit verifizieren, tote MCPs ins Projekt-Repo.
- 'Was du sofort wissen musst' um shelly-mcp-Tote ergänzt.
2026-08-28 14:24:31 +02:00
d30267920a Merge remote-tracking branch 'bf-network-r6/main'
# Conflicts:
#	CLAUDE.md
#	README.md
#	caddy/Caddyfile
#	docs/teilprojekte.md
#	mcp/INVENTORY.md
#	nautobot/mikrotik_routeros.j2
2026-08-27 22:02:40 +02:00
b4419e2d3d mcp/INVENTORY.md: VLAN-Schema 10.40.<vlan>.<oktet>, Omada RETIRED markiert
- Netzwerk-Schema-Hinweis: 10.40.41.x ist tot, alle Hosts auf neues Schema.
- MikroMCP/pve-mcp/komodo-mcp/portainer-mcp: .41.x → .20.x korrigiert.
- omada-mcp + omada-controller: ⛔ RETIRED 2026-08-27 (Omada-Stack raus).
- 'Claude Code' → 'opencode' (Tool-Wechsel, s. Inventur-Handoff).
- 'später'/'Router-Cutover' Phrasen an aktuelle Realität angepasst.
2026-08-27 21:44:08 +02:00
c2b075eaf1 claude.md: Pflichtlektüre + Master-Struktur gekürzt, Lessons for Sessions ergänzt
- Header (Z.1–23): Inventur-Hinweise rein, Master-Struktur (bf-infra/bf-network-r6/
  bf-golden-config/blaueblueten-n8n) als eigener Block, terpene-Stand.
- Pflichtlektüre-Reihenfolge explizit (1. teilprojekte.md Quick-Index, 2. handoff,
  3. cf-tunnel-mapping/archiv bei Bedarf, 4. Inventur-Handoff).
- 'Lessons for Sessions' als neuer Abschnitt am Ende: 4 Verhaltensregeln
  (Bestandsaufnahme vor Plan, große Fragenrunde, Master-Frage früh,
  Drift vor Lösungen) + Checkliste vor Edit-Vorschlägen.
2026-08-27 21:36:46 +02:00
218b79188b inventur + tp34: Architektur-Vorschlag Caddyfile-via-Nautobot/GC
- Handoff-Datei docs/handoff-20260827-inventur-und-architektur.md mit Drift-Befund
  (10 Punkte), Asymmetrie (bf-infra lokal-only / bf-golden-config Gitea-only),
  Inventar-Entscheidung, Architektur-Skizze (Nautobot-Datenmodell +
  GC-Workflow), Übergangsplan, Selbstkritik.
- TP34 in docs/teilprojekte.md als Stub mit Verweis auf Handoff-Architektur-
  Abschnitt. Quick-Index-Eintrag (Zeile 207).
- Erster Anwendungsfall: terpene.teilzeitladen.xyz (Mac-mini-Backend
  10.40.20.167:8890, Caddy-Block kommt als Quick-Win).
2026-08-27 21:35:53 +02:00
8d2b4a71e4 aufräumen: Inventar-Pipeline stillgelegt, Root-handoff ins docs/, README präzisiert
- inventory/*: build.py/XLSX-Pipeline seit 2025-06 stale, Inventar erneuert sich
  nicht seit Core-Cutover; MikroMCP/CF/Portainer liefern Live-Daten.
- handoff.md → docs/handoff-20260827-hubert-und-altlasten.md (Konventionsbruch
  aus der aktuellen Session korrigiert)
- README.md: komplettes Rewrite mit Master-Struktur-Tabelle (bf-infra aktiv,
  bf-network-r6 Archiv, bf-golden-config Bot), Übergangspfad, Status-Block
2026-08-27 21:34:58 +02:00
1d307721ad TP23 Stufe 2 + TP31 Schritt 4: AdGuard split-horizon mit .bf.-Suffix, Caddyfile .bf.-FQDNs
- AGH 110/111: conditional upstream [/bf.emsenhuber.net/]10.40.20.1
- 47 Rewrites: 16 Service->Caddy (inkl. .bf.), 10 Hosts mit .bf., suffixlose parallel
- Caddyfile: interne Sites mit .bf.-Alias (public vw/hass/n8n/gitea ohne)
- DHCP: alle 7 VLANs zeigen auf .36/.37 (domain=emsenhuber.net)
- Firewall-Regeln auf .36/.37 bereits scharf
- nas.emsenhuber.net endgueltig entfernt (war schon in 1d569fa)
- Ist-Stand-Block + Status-Tabelle nachgezogen
2026-08-26 21:22:39 +02:00
6234e61c4e transaktionen: agh-bf1-AdGuardHome als Soll-Zustand fuer TP23 Stufe 2
Die Datei war bereits im Working Tree, aber ohne klaren Zweck -- jetzt
umbenannt auf .snapshot.yaml und mit Marker-Kommentar versehen, der sagt:
- das ist KEINE Transaktions-Akte (kein .json)
- das ist auch KEIN Vor-Zustand zum heutigen nas.emsenhuber.net-Edit
- das ist die AGH-Komplett-Config mit bereits angewandtem Standortsuffix
  (*.bf.emsenhuber.net), die beim Bau des AGH-Paars (110/111) in der
  naechsten Session als Soll-Zustand gilt.

upstream_dns ist auf /bf.emsenhuber.net/ bedingt (Suffix-Form), 26 von
30 Rewrites haben .bf.-Suffix, 4 Public (vw/hass/n8n/gitea) bleiben ohne
Suffix.
2026-08-26 21:01:01 +02:00
8a3601d95e handoff: 2026-08-26 — TP31 Schritt 4 fortsetzen + Suffix-Sweep
Baut auf handoff-20260825 auf (AdGuard-Paar + Split-Horizon) und ergaenzt
den Auftrag um den heute eingefuehrten Standortsuffix-Sweep: alle BF-Hosts
in AGH heissen kuenftig <host>.bf.emsenhuber.net statt ohne Suffix.

nas.emsenhuber.net ist seit 1d569fa weg (Commit direkt vorher).
2026-08-26 20:58:51 +02:00
1d569fa0f5 TP31: nas.emsenhuber.net entfernt, Standortsuffix als Regel
`nas.emsenhuber.net` war nur als AGH-Rewrite auf 10.40.20.10 vorhanden,
zeigte aber nirgends hin: kein CF-CNAME, kein Caddyfile-Eintrag (der
hatte von Anfang an ds-bf.emsenhuber.net fuer Synology DSM).

Mit dem TP23-Stufe-2-Cutover wandert die DNS-Aufloesung in ein
AdGuard-Paar und der Rewrite-Satz wird neu aufgebaut. Die Regel
ist ab jetzt: Hosts, die es an mehreren Standorten gibt, heissen
immer `<host>.<site>.emsenhuber.net` — kein gemeinsamer Name
ohne Suffix.

Andere namensgleiche Hosts (macmini/mfc/tv/docker/platform-pg/
core/ap1/ap2/branch) bleiben vorerst ohne Suffix in AGH und werden
einzeln in der TP23-Stufe-2-Session bewertet.
2026-08-26 20:57:21 +02:00
535a3bd7b9 TP23 Stufe 2: AGH-Paar als DNS-Resolver + DHCP auf emsenhuber.net
- adguard/AdGuardHome.yaml: AGH-Wizard-Setup (27 Rewrites ohne .bf, DoH zum CF-Gateway, conditional emsenhuber.net).
- nautobot/mikrotik_routeros.j2: DHCP dns-server=10.40.20.36,.37, domain=emsenhuber.net.
- docs/transaktionen/TP23-agh-firewall.commands.rsc: TP5-E2 LAN->AGH dns auf .16/.17 ersetzt durch .36/.37.
- docs/transaktionen/TP23-agh-dhcp-cutover.commands.rsc: DHCP-Cutover (dns-server + domain in einem Deploy).

Compliance 104/104, 0 Drifts. Core bleibt als Rückfallebene unangetastet.

[KEIN go fuer den Rest: Persistenz (CLAUDE.md/memory), Host.Naming (.host.emsenhuber.net),
add-dns-entries-Suffix, conditional-Upstream, lease-time-Transaktion, TP31-defer — alles im Plan,
Wartet auf separates go des Users.]
2026-08-26 20:26:41 +02:00
04abb5a620 opencode: /handoff als JSON-Command (statt .opencode/commands/) 2026-08-26 17:58:37 +02:00
c031f2be64 handoff: 2026-08-26 — AdGuard DNS-Cutover fortsetzen (TP23/TP31) 2026-08-26 17:51:07 +02:00
aa1cc0505d /handoff: Custom Command für Session-Übergabe (generate + resume) 2026-08-26 16:57:54 +02:00
9b60bcc43a opencode: Permission + Quick-Index + TP-Management-Regel
- opencode.jsonc: permission=allow + mikromcp/pve-mcp/home-assistant/cloudflare MCPs
- docs/teilprojekte.md: Quick-Index-Tabelle (22 Zeilen) für 1-Read-Statusbaum
- CLAUDE.md: TP-Management-Regel (vorschlagen -> abstimmen -> anlegen)
2026-08-26 13:39:41 +02:00
5ee0716dda Initial import from bf-network-r6.opencode — opencode migration 2026-08-26 12:44:21 +02:00
de5429de43 Vier gestoppte Gaeste abgeraeumt: 103, 109, 115, 201
User-Entscheid. minarca, node-red, hms-mqtt-publisher und openproject
zerstoert, 28 PBS-Snapshots geloescht, 0 Fehler. Gegenprobe direkt am
Datastore: keine Spur von ct/103|109|115|201 mehr.

Ergebnis: auf pve laeuft jetzt jeder existierende Gast -- 11 LXC + 2 VMs,
kein einziger stopped. Der Datastore enthaelt nur noch aktuelle Gaeste.

Merkregel mitgeschrieben: die Snapshot-Liste VOR dem pct destroy
einsammeln. pvesm list --vmid liefert danach 0, obwohl die Backups noch
liegen -- der Filter braucht die Gast-Config. Genau deshalb lief der
104er-Loeschversuch vorhin ins Leere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:36:21 +02:00
33edd73b68 Handoff nachgezogen: ct/104-Snapshots sind ebenfalls weg
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:32:43 +02:00
eea9bbe3f8 ct/104-Snapshots weg; Doku nachgezogen
User-Entscheid: auch die Grafana-Backups loeschen. Gegenprobe direkt am
Datastore (ct/104 = 0), nicht ueber 'pvesm list --vmid' -- dessen Filter
ist nach dem destroy nicht mehr aussagekraeftig.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:32:19 +02:00
888f334e05 TP31: tote VLAN1-Adresse aus HAs Trusted-Proxy-Liste entfernt
Christoph hat 10.40.41.10/32 (alte VLAN1-NAS) entfernt und den Stand als
stable bestaetigt - kein pending offen. Vertraut wird jetzt nur noch, was
tatsaechlich proxyt: 10.40.20.40 (Caddy) plus die drei cloudflared-Origins,
die mit Schritt 6 wegfallen. Abnahme: hass/vw/gitea/n8n je 200 ueber Caddy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:27:34 +02:00
663f6987f8 TP31: hass-400 geloest - HA ignoriert den http-Block in der YAML
Ursache war nicht der fehlende Eintrag, sondern der falsche Ort: HA hat die
http-Konfiguration nach .storage/http migriert ("yaml_migration_done": true,
created_at 2026-08-05). Der YAML-Block wird seither kommentarlos ignoriert -
auch ein absichtlich ungueltiger Schluessel darin erzeugt keinen Fehler.

Die Logzeile fuehrt aktiv in die Irre: "untrusted proxy 10.40.20.40" faellt
laut Quelltext nur bei aktivem use_x_forwarded_for - beide Werte kamen aber
aus .storage, wo .20.10/.126/.167 (die cloudflared-Origins) standen und
Caddy fehlte.

Fix ueber den vorgesehenen Weg: http/config/configure (setzt pending, startet
HA neu) und binnen 5 Minuten http/config/promote. stable enthaelt jetzt
10.40.20.40/32, pending ist leer, hass/vw/gitea/n8n liefern 200 ueber Caddy.

Der wirkungslose Block in configuration.yaml ist durch einen Hinweis ersetzt.
Offen und bewusst vertagt: 10.40.41.10/32 (tote VLAN1-NAS) steht weiter in
der Trusted-Liste.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:21:43 +02:00
6139d8e15e TP31: SoT-Frage beantwortet + cf-sync.py; Uebergabe nach User-Korrekturen
SoT: CF und Caddy werden NICHT synchron gehalten - die Doppelpflege faellt
mit Schritt 5/6 weg. Heute stehen 19 Ingress-Regeln und 16 Caddy-Sites
nebeneinander und stimmen fachlich ueberein; im Zielbild haelt CF nur noch
eine Catch-all auf 10.40.20.40. Danach: Caddyfile = Name->Origin,
CF = welcher Name ist oeffentlich (4), AGH = Name->IP intern.
Nebeneffekt: die 12 internen Namen brauchen keinen oeffentlichen DNS mehr.

caddy/cf-sync.py (read-only, Exit 1 bei Drift) findet im ersten Lauf sieben
Abweichungen, alle auf CF-Seite: grafana noch im Ingress, nautobot und
gateway-dw als CNAME ohne Ingress (Quelle der 302), drei *.bf-CNAMEs auf den
zerstoerten NPM, dazu die Wildcard-Access-App, die alles maskiert.

Uebergabe korrigiert nach User-Einwand und Gegenmessung:
- Rewrites sind veraltet, nicht wertlos - Hosts leben auf VLAN20 weiter,
  also Ziele umbiegen statt Namen loeschen.
- Die Redundanz existiert doch, reziprok ueber die Standorte: FM antwortet
  auf 10.101.0.16/.17 (DS415+) - und beide liefern fuer nas.bf die tote
  VLAN1-Adresse. Ein Rewrite-Satz nur im neuen BF-Paar erzeugt
  standortabhaengig verschiedene Antworten.
- Vorratsregel auf .16 wird gestrichen statt erweitert (User-Entscheid).
- Cave: emsenhuber.net ist die Domain, bf.lan nur der DHCP-Suffix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 00:06:14 +02:00
5b043f1032 Uebergabe Schritt 4 neu gefasst: drei Funde kippen den alten Plan
Die erste Fassung entstand vor der Caddy-Abnahme. Live erhoben, dagegen:

- adguard_bf1 (.20.16) ist ein Archiv, keine Vorlage: 24 Rewrites, davon 8
  ins tote VLAN1, 9 auf den heute zerstoerten nginx-proxy-manager (LXC 128)
  und 2 FritzBox-Reste. Uebernommen werden Upstreams/Filter, die Rewrites
  entstehen neu aus caddy/Caddyfile.
- .20.17 ist nicht "bf2", sondern adguard_fm2 (FM-Standort) und antwortet
  fuer gitea mit 10.40.41.123. BF hat heute EINEN AGH.
- Die TP5-Vorratsregeln erlauben LAN->DNS hart auf .20.16. Nach dem
  DHCP-Flip wird DNS ein forward-Fluss ueber VLAN-Grenzen; ohne erweiterte
  Regeln verlieren IOT/MEDIA/UNTRUSTED/GUEST/MGMT die Aufloesung, waehrend
  VLAN20 weiterlaeuft und den Fehler tarnt.

Dazu neu: lease-time=1d macht Flip und Rollback traege (erst zur
Erneuerung wirksam), expliziter Rollback-Abschnitt, .36/.37 als frei
geprueft, und der Core bleibt bewusst Rueckfallebene.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 23:25:34 +02:00
fef2582174 TP31: Caddy abgenommen (16/16), hass-400 praezisiert statt geraten
Schritt 3 ist durch: Token liegt, deploy.sh gelaufen, Dienst active+enabled.
Abnahme ueber den Host-Header von einem zweiten Host (pve): 11x 200,
nautobot 302, Antwortzeiten 0,02-0,11 s.

Zwei Funde, die man sonst falsch ablegt:
- pve-mcp 400 / ha-mcp 403 / gitea-mcp 404 sind KEINE Proxy-Fehler - die
  Gegenprobe direkt am Origin liefert dieselben Codes. Es sind die Antworten
  der MCP-Server auf ein nacktes GET /.
- hass bleibt 400, aber die Logzeile sagt "untrusted proxy 10.40.20.40" und
  nicht "not set-up for reverse proxies": use_x_forwarded_for greift also,
  nur die Liste zieht nicht. Zwei volle Neustarts, Config-Check valid.
  Naechster Schritt notiert; die atime taugt unter relatime nicht als Beweis.

Ist-Stand-Block mitgezogen (Projektregel).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 22:46:54 +02:00
b77deed46c Uebergabe fuer den AGH-DNS-Cutover als eigene Session
Der Split-Horizon-Entscheid (AdGuard statt Core) macht aus 'ein paar
Eintraegen' eine Verschiebung der DNS-Aufloesung des ganzen Standorts in
einen Container -- heute liefert der DHCP in allen sieben VLANs den Core.
Das gehoert nicht ans Ende einer langen Sitzung (Lehre aus TP28).

Handoff enthaelt: Ausgangslage (Caddy produktiv, 16 Sites/17 Zertifikate),
den Auftrag in fuenf Schritten inkl. der IP-Kollision .30 (Nautobot) und
der Vorgabe, AGH als Paar 110/111 zu bauen statt als DNS-SPOF, sowie die
Staffelung VLAN fuer VLAN mit VLAN30 zuletzt.

Vier Fallen mitgegeben, alle in dieser Session bezahlt: Statuscode vom
oeffentlichen FQDN beweist nichts (grafana), pvesm free scheitert an
geschuetzten Snapshots stillschweigend, Startreihenfolge haengt nicht an
der VMID, und Core-Config braucht Golden Config.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:48:48 +02:00
2fd300f6da TP31: Caddy laeuft (17/17 Zertifikate); grafana als tot entlarvt
Caddy in LXC 130 ist produktiv: 17 von 17 Zertifikaten per DNS-01 von
Let's Encrypt, Dienst active+enabled, Proxy gegen Host-Header verifiziert
(nautobot 302, gitea 200, pve 200, portainer 200). deploy.sh laeuft
End-to-End; Token per Fingerprint gegengeprueft -- eigenes Zone:DNS:Edit,
nicht das account-weite.

🔴 Fund beim Durchtesten: grafana war seit Langem tot und Cloudflare
Access hat es maskiert. LXC 104 stopped, konfigurativ noch auf VLAN1
(10.40.41.109), waehrend die Ingress-Zeile auf 10.40.20.109 zeigte -- eine
Adresse die es fuer Grafana nie gab. Der FQDN lieferte trotzdem 302, weil
das der Access-Login war. Exakt die Falle aus TP16.3 Paragraph 8, diesmal
in freier Wildbahn: ein toter Dienst sieht hinter Access monatelang
gesund aus.
=> Caddy-Zeile raus (16 Sites), LXC 104 zerstoert, aus dem Backup-Job.
Die 14 PBS-Snapshots bleiben bewusst stehen -- einzige Kopie etwaiger
Dashboards.

hass liefert 400: bekannter trusted_proxies-Punkt aus TP16, gehoert vor
die CNAME-Umstellung.

Split-Horizon entschieden (User): in AdGuard zusammen mit TP23 Stufe 2.
Dokumentiert, was das bedeutet -- heute liefert der DHCP in allen sieben
VLANs den Core als DNS; AGH bekommt niemand. Der Schritt verschiebt die
Aufloesung des ganzen Hauses in einen Container, deshalb als Paar
110/111 bauen. Die geloeschten Altlasten hiessen nicht zufaellig
adguard-bf1/-bf2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 20:45:01 +02:00
e0feedeca3 TP7.1: zweite Ursache dokumentiert - die App suchte gar nicht
Nach der Relay-Reparatur lag weiter nichts an. tcpdump auf der VLAN40-Leitung:
jedes SSDP-Paket des MacBooks kam von Chrome (ST dial-multiscreen,
USER-AGENT Chromium), kein einziges von Sonos. Ursache war das
macOS-Local-Network-Gate - es stand auf "an" und griff nicht. Schalter
aus/ein + App-Neustart hat es gerichtet (User-bestaetigt).

Damit faellt auch die tragende Zahl des Vormittags-Handoffs: die "291 Suchen
der App in 12 Minuten" waren Chrome plus eigene Proben.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 18:48:36 +02:00