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.
This commit is contained in:
2026-08-28 19:15:02 +02:00
parent 433e600f83
commit 8c1876c1d6
3 changed files with 89 additions and 4 deletions

View File

@@ -193,6 +193,8 @@ Verhaltensregeln für nachfolgende AI-Sessions — kleiner, klarer, weniger Drif
- **MCPs brauchen Host-Verifikation** vor Edit. Wenn der MCP verändert/editiert wird: vorher per Live-Read (nc/ps/curl) prüfen, ob der Host noch antwortet. Beispiel: 2026-08-27 — `shelly-mcp` zeigte auf `10.40.20.30:3030`, aber kein Host antwortet. Konfig auf `enabled=false`, dokumentieren statt hart fehlschlagen zu lassen. **(Stand 2026-08-28: shelly-mcp wird auf DS923 `10.40.20.180` deployt — `BUILD.md` liegt bereit.)**
- **Mac mini ist n8n-Host, nicht zentraler MCP-Host** (User-Direktive 2026-08-28): MCP-Dienste gehören auf die **DS923** (`nas-bf`, Portainer Endpoint 14) — nicht auf die User-Workstation. Aktuell laufen gitea-mcp + n8n-mcp **noch** auf dem macmini (historisch), gehören **bei Gelegenheit** auf die DS923 umgezogen.
- **Tote MCP-Skripte → ins Projekt-Repo, nicht global.** Wenn ein MCP nur für ein Projekt relevant ist (`cannaleo` für terpene, `terpene-pg` für terpene): gehört in `~/dev/<projekt>/mcp.json` + Skript im Projekt-Repo. Globale `~/.claude.json`/`~/.config/opencode/opencode.jsonc` = nur projekt-übergreifende Tools.
- **opencode-Skills: Default-Pfad kopieren, NICHT symlinken** (TP35 Schicht 6, 2026-08-28). Claude-Skill in `~/.claude/skills/<name>/SKILL.md` ist die Quelle; für opencode gehört er nach `~/.config/opencode/skills/<name>/SKILL.md` (`cp`, nicht `ln -s`). Begründung: opencode scannt diesen Pfad als Default — **kein** `skills.paths`-Eintrag in `~/.config/opencode/opencode.jsonc` nötig, das wäre redundant. Symlink wurde in der Inventur-Session testweise angelegt, hat Christophs "opencode = eigene Pfade"-Direktive verletzt und wurde wieder entfernt. Schema-Referenz: <https://opencode.ai/config.json> → `Config.skills.paths`. **Lehre aus dem Fall:** opencode-CLI-Verhalten nicht raten, Doku lesen — und ein "load-bearing"-Detail (Default-Scan-Pfad) zuerst verifizieren, bevor man ihn umgeht.
- **Kommentar in Code ≠ Verhalten.** `mcp/shelly/.env` trug den Kommentar "gitignored, NICHT committen" — es gab aber **kein** `mcp/shelly/.gitignore`. Der Kommentar war Wunsch, nicht Wirklichkeit. `routeros/cloudflared/credentials.json` (Cloudflare-Tunnel-PrivateKey base64) lag ungegittoret im Working Tree. **Merkregel:** Behauptungen in Kommentaren/Konfig-Kommentaren durch `git check-ignore -v <datei>` (oder `git status`) verifizieren, bevor man darauf vertraut. **Lessons-Block erweitert 2026-08-28 nach `commit`-Session.**
**Checkliste vor jedem Edit-Vorschlag:**

View File

@@ -0,0 +1,82 @@
# Handoff 2026-08-28 — Session A (TP35 Schicht 6: /projektstatus-Skill für opencode)
> **Bezug:** Handoff 2026-08-28 Bestand + Performance (`handoff-20260828-mcp-bestand-und-performance.md`)
> → diese Session A (eine von drei Folge-Sessions aus dem obigen Handoff).
> Diese Datei: **was in Session A passiert ist**, **was bleibt**, **Einstieg für Session B (shelly-mcp-Deploy)**.
## TL;DR
- **`/projektstatus`-Skill läuft jetzt in opencode.** Kopie (`cp`, kein `ln -s`) nach `~/.config/opencode/skills/projektstatus/SKILL.md`.
- **Kein** `skills.paths`-Eintrag in `~/.config/opencode/opencode.jsonc` nötig — opencode scannt den Default-Pfad.
- **Lehre** im CLAUDE.md-Lessons-Block: Default-Pfad kopieren, nicht symlinken, keine `skills.paths`-Konfiguration.
- **Doku nachgezogen:** TP35 Schicht 6 als ✅, Quick-Index ⏳ (Rest offen), Ist-Stand-Block auf 2026-08-28 mit MCP-Bestand-Korrektur.
## Was war (Drift → Befund → Entscheid)
### Drift
- Im gestrigen Handoff (`handoff-20260828-mcp-bestand-und-performance.md`) stand, der testweise angelegte Symlink `~/.config/opencode/skills/projektstatus → ~/.claude/skills/projektstatus/` sei wieder entfernt worden. Wahr: das Verzeichnis `~/.config/opencode/skills/` existierte danach **nicht** mehr, opencode fand den Skill nicht.
- Christoph-Direktive (verbatim aus CLAUDE.md-Lessons): "opencode ist die neue Umgebung, soll eigene Skill-Pfade haben, keine Symlinks". Frage: **wohin genau?** war offen.
### Befund (verifiziert, nicht geraten)
- opencode-Schema aus `https://opencode.ai/config.json` (gefetched und gelesen): `skills.paths: string[]` ist der dokumentierte Multi-Pfad-Loader.
- **Globale Default-Pfade** lauten `~/.config/opencode/skill/<name>/SKILL.md` und `~/.config/opencode/skills/<name>/SKILL.md` (beide Singular/Plural) — und zusätzlich scannt opencode `~/.claude/skills/<name>/SKILL.md` und `~/.agents/skills/<name>/SKILL.md` als **externe** Skills (auto-loaded).
- Die Lehrstelle gestern war ein Holzweg: Symlink-Workaround für etwas, wofür das Schema einen eingebauten Default-Pfad hat.
### Entscheid
- **Kopie** der `SKILL.md` nach `~/.config/opencode/skills/projektstatus/` — keine Konfigurationsänderung an `opencode.jsonc`.
- Begründung: hält die Welten sauber getrennt (zwei Pflegeorte für spätere Drift-Reparaturen), nutzt den opencode-Default-Pfad ohne Sonderlock, vermeidet die gestern explizit abgelehnte Symlink-Lösung.
### Verifikation
- `cp` lief, `diff -q ~/.claude/skills/projektstatus/SKILL.md ~/.config/opencode/skills/projektstatus/SKILL.md` → **byte-identisch** (kein Output = identisch).
- Berechtigungen symmetrisch zur Quelle (`-rw-r--r--`).
- `opencode.jsonc` ist **unverändert** (kein Backup nötig, kein Diff).
- **Was die nächste Sitzung bestätigen muss:** opencode neu starten, `/projektstatus` triggern, den Baum lesen — der eigentliche Funktionsbeweis steht noch aus.
## Was sich geändert hat (in dieser Session, im Repo)
| Datei | Änderung |
|---|---|
| `CLAUDE.md` (Lessons) | Zwei neue Einträge: (a) "opencode-Skills: Default-Pfad kopieren, NICHT symlinken" mit Schema-Referenz; (b) "Kommentar in Code ≠ Verhalten" als Generalisierung des credentials.json/.env-gitignore-Funds aus dem Commit-Schritt. |
| `docs/teilprojekte.md` Quick-Index Z. 208 | TP35: `🔜 → ⏳` (Schicht 6 ✅, Rest offen). |
| `docs/teilprojekte.md` TP35-Block Z. 1747 | Schicht 6 als ✅ markiert, Datum 2026-08-28, Befund-Block. |
| `docs/teilprojekte.md` Ist-Stand Z. 28 | Datum auf 2026-08-28, neue Bullet-Zeile MCP-Bestand-Korrektur. |
**Was bewusst NICHT geändert wurde:**
- `opencode.jsonc` — der Pfad ist Default-Scan, kein Eintrag nötig.
- `~/.claude/skills/projektstatus/` — die Quelle, bleibt unverändert.
- `docs/handoff-20260828-mcp-bestand-und-performance.md` — gestern abgeschlossen, nicht überschrieben.
## Sicherheitsfund (nicht-Session-A-Arbeit, aber heute aufgetaucht)
Beim `commit`/`push` der untracked Session-B-Vorbereitung:
- `routeros/cloudflared/credentials.json` (Tunnel-PrivateKey base64) lag ungegittoret im Working Tree.
- `mcp/shelly/.env` trug den Kommentar "gitignored, NICHT committen" — es gab aber **kein** `mcp/shelly/.gitignore`.
- **Beide gefixt** in den Commits `27863c1` und `433e600` (siehe Lessons-Block).
- Working Tree ist clean, kein Secret jemals in den Index geraten.
## Drei Folge-Sessions — was ist abgearbeitet, was steht
| Session | Status |
|---|---|
| **A** — `/projektstatus`-Skill global | ✅ erledigt (diese Datei) |
| **B** — shelly-mcp-Container auf DS923 deployen (live, ssh) | 🔜 vorbereitet (Repo-Materialien committed `27863c1`, .env lokal) |
| **C** — Caddyfile↔CF-Ingress-Drift-Probe + Backup-Guard | 🔜 unangetastet |
## Lehren für die nächste Session (B)
1. **Live-Sweep am 2026-08-28 hat 23 Shellys auf VLAN30 bestätigt** (`.30.202`–`.226` + `.233`). `SHELLY_SWEEP=10.40.30.180-250` in `~/.secrets/exports.zsh` ist die Range, in der die echten Geräte **alle** liegen — die zusätzlichen 50 IPs sind Reserve, kein toter Sweep-Bereich.
2. **Container-Pfad** = DS923 (`10.40.20.10`), NICHT macmini. Macmini belasten wir nicht, das war Christoph-Direktive.
3. **Container-Definition lebt NICHT in `docs/nas-vlan20/stacks/shelly-mcp.yml`** — der wurde gestern gelöscht (User-Direktive: kein MCP-Client für shelly-mcp). Deployment = direkt via Portainer-API, nicht als Stack.
4. **DHCP-Reservierung** = `crs326-core` `dhcp-v20`, MAC nach erstem Boot per MikroMCP `manage_dhcp_lease make-static` festnageln.
5. **WLAN-PSKs** in `SHELLY_IOT_PSK` / `SHELLY_DEVICE_PW` (aus `~/.secrets/credentials.env`) — **niemals** ins Repo oder in den Container-Image.
## Commit
- **Hash:** siehe `git log --oneline -1` nach diesem Handoff.
- **Geänderte Dateien:** `CLAUDE.md`, `docs/teilprojekte.md`, neue Datei `docs/handoff-20260828-session-a-projektstatus.md`.
- **Commit-Message (Vorschlag):** `TP35 Schicht 6: /projektstatus-Skill in opencode aktiviert + Doku nachgezogen`
## Stand
- 2026-08-28, ~19:30
- Diese Session = Skill-Pfad-Findung + Kopie + Lessons-Eintrag + TP35/Ist-Stand-Update + Handoff
- Sessions B + C aus dem gestrigen Handoff unverändert
- `~/.config/opencode/opencode.jsonc` ist unverändert (kein Backup)

View File

@@ -27,10 +27,11 @@ Mgmt (VLAN99, Ist 2026-08-16): core `.99.1` · branch `.99.2` · ap1 `.99.11` ·
## Ist-Stand (Kurz)
**Stand 2026-08-26 — live gegen die Geräte geprüft (MikroMCP/REST), nicht aus der Doku abgeschrieben.**
**Stand 2026-08-28 — live gegen die Geräte geprüft (MikroMCP/REST), nicht aus der Doku abgeschrieben.**
**Die Compliance-Zeile unten ist am 2026-08-23 gegen die Nautobot-API nachgezogen.**
*(Die Fassung vom 2026-08-16 stand bis zum 18. hier und war an vier Stellen überholt. Wer diesen Block
liest, liest ihn als Erstes: er wird bei jeder Änderung mitgezogen, nicht nur die TP-Abschnitte.)*
- 🆕 **MCP-Bestand 2026-08-28 korrigiert:** **9 MCPs identisch** in `~/.claude.json` und `~/.config/opencode/opencode.jsonc` (vorher Asymmetrie 7 vs. 11 — `portainer-mcp`/`shelly-mcp` raus, `gitea-mcp`/`n8n-mcp` rein). **Mac mini = n8n-Host, NICHT zentraler MCP-Host** (Performance-Restriktion); zentraler MCP-Host = **DS923** (`nas-bf`, Portainer Endpoint 14). Inventur-Stand `mcp/INVENTORY.md` + Policy `docs/mcp-host-policy.md`.
- **Alle vier MikroTik laufen auf RouterOS 7.24** (stable, 2026-08-17 von Christoph selbst gehoben, TP27),
**RouterBOOT ebenfalls 7.24** auf allen vieren (`current-firmware` = `upgrade-firmware`, geprüft 08-18).
@@ -205,7 +206,7 @@ nachmessen und dann entscheiden**. Blocker gibt es keine mehr. TP5 ist in der Na
> | TP32 | 🟢 | Nummern-Systematik (Konzept) | — |
> | TP33 | 💡 | Sonos fern (Idee, zurückgestellt) | — |
> | TP34 | 🔜 | Caddyfile via Nautobot/GC (Stub, Inventur-Handoff 2026-08-27) | — |
> | TP35 | 🔜 | MCP-Schichtung + 3-Schicht-CLAUDE.md + Backup-Guard | — |
> | TP35 | ⏳ | MCP-Schichtung + 3-Schicht-CLAUDE.md + Backup-Guard (Schicht 6 ✅) | — |
> | — | — | **34 archivierte TPs** in `teilprojekte-archiv.md` | — |
### TP5.1 — DNS-Visibility & Flow-Observability für Low-Trust-Geräte (Airfryer-Fall) ▸ vorgemerkt
@@ -1753,11 +1754,11 @@ kann in Ruhe nachziehen.
3. **3-Schicht-CLAUDE.md** — `CLAUDE.md` (öffentlich) / `CLAUDE.local.md` (gitignored) / `~/.claude/CLAUDE.md` (global).
4. **Announcement-Mechanismus (Hybrid)** — zentraler Ort (voraussichtlich `bf-infra/docs/announcements.md`) + Skill `/news` oder `/announce` zum Einlesen beim Session-Start. Initial: Breaking News über die MCP-Schichtung selbst.
5. **Backup-Guard** — `~/dev/.bin/backup-guard.sh`, Pre-Commit-Hook pro Projekt, „3 Tage aktiv"-Definition: 5 Commits oder 1000 LOC diff.
6. **`/projektstatus`-Skill global** — als Erstes, vor den anderen Schichten. Alle Projekte verwenden dasselbe Skill.
6. **`/projektstatus`-Skill global** — als Erstes, vor den anderen Schichten. Alle Projekte verwenden dasselbe Skill. **✅ 2026-08-28:** `/projektstatus`-Skill nach `~/.config/opencode/skills/projektstatus/SKILL.md` kopiert (`cp`, nicht `ln -s`) — opencode scannt diesen Default-Pfad, kein `skills.paths`-Eintrag in der JSONC nötig. Lehre im CLAUDE.md-Lessons-Block.
- **Abgrenzung:** TP35 ist Konzept + Schichtung, nicht die Umsetzung. Pro Projekt eigene Session, eigener Handover-Post, eigene Mini-Anpassung.
- **Verzahnt mit:** TP30 (Credentials), TP34 (Repository-Pattern), TP22 (Nautobot-GC als Vorbild für SSoT + Compliance), TP11 (Monitoring).
- **Erste Session für Scope-Ausarbeitung:** Schichten 1–5 + Skill-Setup; Handover-Posts pro Projekt (Schicht 3 + 4 ergeben die Posts).
- **Referenzen:** Handoff 2026-08-28 (`docs/handoff-20260828-pre-opencode-migration.md`) · Backups `~/dev/.pre-opencode-migration-backups/20260828-150335/` · MCP-Inventur `bf-infra/mcp/INVENTORY.md` · Lessons `bf-infra/CLAUDE.md` Abschnitt „Lessons for Sessions".
- **Referenzen:** Handoff 2026-08-28 (`docs/handoff-20260828-pre-opencode-migration.md`) · Backups `~/dev/.pre-opencode-migration-backups/20260828-150335/` · MCP-Inventur `bf-infra/mcp/INVENTORY.md` · Lessons `bf-infra/CLAUDE.md` Abschnitt „Lessons for Sessions" · `docs/handoff-20260828-mcp-bestand-und-performance.md` (MCP-Bestand-Korrektur + Mac-mini-Restriktion).
---