*State:* Ich konnte `#it-service` nicht direkt lesen: Slack meldet `not_in_channel`. Über die lokalen Handoff-/Memory-Dateien habe ich den Stand seit *17.06.2026 00:00 UTC* trotzdem rekonstruiert.

*Findings:*
- `n8n` ist auf IT15-ArgoCD migriert: `pidoka-n8n` und Secrets zuletzt `Synced / Healthy`.
- `Matomo` wurde nach `pidoka-hf-matomo` migriert und Cutover gemacht. Extern `https://matomo.heckenfels.com/` zuletzt HTTP `200`. Alte `hf-matomo` Ressourcen bleiben als Rollback-Pfad erhalten.
- `Mautic` wurde clean neu aufgebaut. App/DB/Cron laufen, aber Installer unter `https://mautic.heckenfels.com` ist noch offen.
- `Zammad` wurde GitOps-adoptiert und Secrets/ESO sind synchronisiert. Danach Longhorn-Migration vorbereitet/durchgeführt: zuletzt `service.heckenfels.com` HTTP `200`, Pods Running, neue Longhorn-PVCs healthy. Alte `local-path` PVCs bleiben behalten.
- Offener technischer Punkt bei Zammad: Workloads sind wegen alter Bitnami-Image-Tags aktuell auf `mbrkanov-mini-it13` gepinnt. Image-/Registry-Strategie muss bereinigt werden, damit der `nodeSelector` wieder weg kann.
- Weiterhin bekannt: lokale uncommitted Änderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`, nicht Teil der späteren Arbeiten.

*Recommendation:* Heute zuerst read-only Status prüfen:
1. IT15-ArgoCD Apps: `pidoka-n8n`, `pidoka-hf-matomo`, `pidoka-hf-mautic`, `pidoka-hf-zammad`, Secrets-Apps.
2. DMZ Pods/PVCs/ESO für Matomo, Mautic, Zammad.
3. Externe HTTP-Checks für `matomo.heckenfels.com`, `mautic.heckenfels.com`, `service.heckenfels.com`.
4. Danach priorisiert: Mautic Installer abschließen oder Zammad Image-Tags bereinigen.

*Needs OK:* Für echte Channel-Historie bitte kube-bot wieder in `#it-service` einladen. Cluster-Änderungen mache ich weiter nur mit deinem expliziten OK.

Gestern nach 00 Uhr war die Verbindung weg. Kannst mal im Channel die Nachrichten bis dahin durchgehen, damit Du weißt was heute angesagt ist.

bash

/bin/bash -lc "sed -n '1,220p' /usr/local/lib/node_modules/openclaw/skills/slack/SKILL.md"

/bin/bash -lc "sed -n '1,220p' /usr/local/lib/node_modules/openclaw/skills/slack/SKILL.md"

---
name: slack
description: "Slack tool actions: send/read/edit/delete messages, react, pin/unpin, list pins/reactions/emoji, member info."
metadata: { "openclaw": { "emoji": "💬", "requires": { "config": ["channels.slack"] } } }
---

# Slack

Use the `slack` tool. Reuse `channelId` and Slack timestamp message IDs from context when present.

## Inputs

- `channelId`: Slack channel ID.
- `messageId`: Slack timestamp, e.g. `1712023032.1234`.
- `to`: `channel:<id>` or `user:<id>` for sends.
- `emoji`: Unicode or `:name:` for reactions.

## Actions

```json
{ "action": "sendMessage", "to": "channel:C123", "content": "Hello" }
```

```json
{ "action": "readMessages", "channelId": "C123", "limit": 20 }
```

```json
{
  "action": "react",
  "channelId": "C123",
  "messageId": "1712023032.1234",
  "emoji": ":white_check_mark:"
}
```

```json
{ "action": "reactions", "channelId": "C123", "messageId": "1712023032.1234" }
```

```json
{
  "action": "editMessage",
  "channelId": "C123",
  "messageId": "1712023032.1234",
  "content": "Updated text"
}
```

```json
{ "action": "deleteMessage", "channelId": "C123", "messageId": "1712023032.1234" }
```

```json
{ "action": "pinMessage", "channelId": "C123", "messageId": "1712023032.1234" }
```

```json
{ "action": "unpinMessage", "channelId": "C123", "messageId": "1712023032.1234" }
```

```json
{ "action": "listPins", "channelId": "C123" }
```

```json
{ "action": "memberInfo", "userId": "U123" }
```

```json
{ "action": "emojiList" }
```

## Safety

- Confirm destructive deletes when context is unclear.
- Keep outbound messages short; avoid Markdown tables.
- Prefer thread/message IDs over fuzzy channel names.

/bin/bash -lc "pwd && rg --files -g 'AGENTS.md' -g 'SESSION_HANDOFF.md' -g 'INFRASTRUCTURE.md' -g '*.md'"

/bin/bash -lc "pwd && rg --files -g 'AGENTS.md' -g 'SESSION_HANDOFF.md' -g 'INFRASTRUCTURE.md' -g '*.md'"

/home/node/.openclaw/workspace
INFISICAL_ARGO_K3S_KONZEPT.md
PLATFORM_AUFGABEN_KUBE_BOT.md
OPNSENSE_INFISICAL_PAUSE_NOTES.md
inventory/argocd-mandanten-migrationsmatrix-20260615.md
inventory/longhorn-health-report.md
inventory/argocd-readiness-20260615/README.md
inventory/service-matrix.md
inventory/layered-inventory.md
inventory/professionalization-priorities.md
inventory/backup-strategy-draft.md
memory/2026-06-17.md
memory/2026-06-15.md
ARGOCD_IT15_INFISICAL_PIDOKA_PLAN.md
INFISICAL_IT15.md
BETRIEBSKONZEPT_PLATFORM.md
USER.md
HEARTBEAT.md
SOUL.md
INFRASTRUCTURE.md
backup-plans/longhorn-restore-return-path-addendum.md
backup-plans/longhorn-restore-test-kube-review.md
SESSION_HANDOFF.md
TOOLS.md
AGENTS.md
TOMORROW_DMZ_INFISICAL.md
IDENTITY.md
camofox-browser/README.md
camofox-browser/AGENTS.md
audits/argocd-repo-20260615/README.md
audits/argocd-repo-20260615/git-history-secret-scan-summary.md
audits/argocd-repo-20260615/secret-scan-summary.md
camofox-browser/plugins/persistence/README.md
camofox-browser/plugins/persistence/AGENTS.md
camofox-browser/plugins/youtube/AGENTS.md
camofox-browser/plugins/vnc/README.md
camofox-browser/plugins/vnc/AGENTS.md
camofox-browser/node_modules/ini/README.md
camofox-browser/node_modules/statuses/README.md
camofox-browser/node_modules/statuses/HISTORY.md
camofox-browser/node_modules/minimatch/README.md
camofox-browser/node_modules/minimatch/LICENSE.md
camofox-browser/node_modules/xml2js/README.md
camofox-browser/node_modules/simple-concat/README.md
camofox-browser/node_modules/callsites/readme.md
camofox-browser/node_modules/decompress-response/readme.md
camofox-browser/node_modules/safer-buffer/Porting-Buffer.md
camofox-browser/node_modules/safer-buffer/Readme.md
repos/platform-gitops/README.md
repos/old-argocd/README.md
camofox-browser/node_modules/fast-deep-equal/README.md
camofox-browser/node_modules/base64-js/README.md
camofox-browser/node_modules/serve-static/README.md
camofox-browser/node_modules/serve-static/HISTORY.md
camofox-browser/node_modules/negotiator/README.md
camofox-browser/node_modules/negotiator/HISTORY.md
camofox-browser/node_modules/end-of-stream/README.md
camofox-browser/node_modules/pretty-bytes/readme.md
camofox-browser/node_modules/utils-merge/README.md
camofox-browser/node_modules/chownr/README.md
camofox-browser/node_modules/swagger-jsdoc/README.md
camofox-browser/node_modules/tar-fs/README.md
camofox-browser/node_modules/shebang-regex/readme.md
camofox-browser/node_modules/node-releases/README.md
camofox-browser/node_modules/language-tags/README.md
camofox-browser/node_modules/has-symbols/README.md
camofox-browser/node_modules/minipass/README.md
camofox-browser/node_modules/minipass/LICENSE.md
camofox-browser/node_modules/tslib/README.md
camofox-browser/node_modules/tslib/SECURITY.md
camofox-browser/node_modules/call-bind-apply-helpers/README.md
camofox-browser/node_modules/array-flatten/README.md
camofox-browser/node_modules/get-intrinsic/README.md
camofox-browser/node_modules/vary/README.md
camofox-browser/node_modules/tunnel-agent/README.md
camofox-browser/node_modules/vary/HISTORY.md
camofox-browser/node_modules/call-bind-apply-helpers/CHANGELOG.md
camofox-browser/node_modules/es-object-atoms/README.md
camofox-browser/node_modules/tiny-lru/README.md
camofox-browser/node_modules/shebang-command/readme.md
camofox-browser/node_modules/es-errors/README.md
camofox-browser/node_modules/es-object-atoms/CHANGELOG.md
camofox-browser/node_modules/fingerprint-generator/README.md
camofox-browser/node_modules/fingerprint-generator/LICENSE.md
camofox-browser/node_modules/type-is/README.md
camofox-browser/node_modules/type-is/HISTORY.md
camofox-browser/node_modules/get-intrinsic/CHANGELOG.md
camofox-browser/node_modules/minimist/README.md
camofox-browser/node_modules/path-key/readme.md
camofox-browser/node_modules/buffer/README.md
camofox-browser/node_modules/buffer/AUTHORS.md
camofox-browser/node_modules/has-symbols/CHANGELOG.md
camofox-browser/node_modules/es-errors/CHANGELOG.md
camofox-browser/node_modules/impit-linux-x64-gnu/README.md
camofox-browser/node_modules/unpipe/README.md
camofox-browser/node_modules/unpipe/HISTORY.md
camofox-browser/node_modules/camoufox-js/README.md
camofox-browser/node_modules/raw-body/README.md
camofox-browser/node_modules/camoufox-js/LICENSE.md
camofox-browser/node_modules/on-finished/README.md
camofox-browser/node_modules/on-finished/HISTORY.md
camofox-browser/node_modules/express/Readme.md
camofox-browser/node_modules/adm-zip/README.md
camofox-browser/node_modules/generative-bayesian-network/README.md
camofox-browser/node_modules/generative-bayesian-network/LICENSE.md
camofox-browser/node_modules/math-intrinsics/README.md
camofox-browser/node_modules/range-parser/README.md
camofox-browser/node_modules/range-parser/HISTORY.md
camofox-browser/node_modules/brace-expansion/README.md
camofox-browser/node_modules/bindings/README.md
camofox-browser/node_modules/bindings/LICENSE.md
camofox-browser/node_modules/which/README.md
repos/platform-gitops/tenants/cattaro/stage/README.md
camofox-browser/node_modules/minimist/CHANGELOG.md
camofox-browser/node_modules/playwright-core/README.md
camofox-browser/node_modules/which/CHANGELOG.md
camofox-browser/node_modules/math-intrinsics/CHANGELOG.md
camofox-browser/node_modules/swagger-jsdoc/node_modules/commander/Readme.md
camofox-browser/node_modules/express/History.md
camofox-browser/node_modules/tdigest/README.md
camofox-browser/node_modules/swagger-jsdoc/node_modules/commander/CHANGELOG.md
camofox-browser/node_modules/encodeurl/README.md
camofox-browser/node_modules/string-width/readme.md
camofox-browser/node_modules/call-me-maybe/README.md
repos/platform-gitops/tenants/pidoka/stage/README.md
camofox-browser/node_modules/swagger-jsdoc/node_modules/glob/README.md
camofox-browser/node_modules/swagger-jsdoc/node_modules/glob/LICENSE.md
camofox-browser/node_modules/jackspeak/README.md
camofox-browser/node_modules/jackspeak/LICENSE.md
camofox-browser/node_modules/sax/README.md
camofox-browser/node_modules/sax/LICENSE.md
camofox-browser/node_modules/better-sqlite3/README.md
camofox-browser/node_modules/@types/json-schema/README.md
camofox-browser/node_modules/doctrine/README.md
camofox-browser/node_modules/@sindresorhus/is/readme.md
camofox-browser/node_modules/update-browserslist-db/README.md
camofox-browser/node_modules/doctrine/CHANGELOG.md
camofox-browser/node_modules/merge-descriptors/README.md
camofox-browser/node_modules/merge-descriptors/HISTORY.md
repos/platform-gitops/tenants/pidoka/prod/matomo/README.md
camofox-browser/node_modules/mime-db/README.md
camofox-browser/node_modules/mime-db/HISTORY.md
camofox-browser/node_modules/media-typer/README.md
camofox-browser/node_modules/media-typer/HISTORY.md
camofox-browser/node_modules/browserslist/README.md
camofox-browser/node_modules/forwarded/README.md
camofox-browser/node_modules/forwarded/HISTORY.md
camofox-browser/node_modules/etag/README.md
camofox-browser/node_modules/etag/HISTORY.md
camofox-browser/node_modules/dunder-proto/README.md
camofox-browser/node_modules/emoji-regex/README.md
repos/platform-gitops/tenants/pidoka/prod/n8n/README.md
camofox-browser/node_modules/dunder-proto/CHANGELOG.md
camofox-browser/node_modules/safe-buffer/README.md
camofox-browser/node_modules/finalhandler/README.md
camofox-browser/node_modules/finalhandler/HISTORY.md
camofox-browser/node_modules/finalhandler/SECURITY.md
camofox-browser/node_modules/rc/README.md
camofox-browser/node_modules/escalade/readme.md
camofox-browser/node_modules/vali-date/readme.md
camofox-browser/node_modules/@isaacs/cliui/README.md
camofox-browser/node_modules/@isaacs/cliui/LICENSE.md
camofox-browser/node_modules/iconv-lite/README.md
camofox-browser/node_modules/iconv-lite/Changelog.md
camofox-browser/node_modules/glob/README.md
camofox-browser/node_modules/glob/LICENSE.md
repos/platform-gitops/tenants/pidoka/prod/mautic/README.md
camofox-browser/node_modules/side-channel-weakmap/README.md
camofox-browser/node_modules/bintrees/README.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/storage-state.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/tracing.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/test-generation.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/element-attributes.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/running-code.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/session-management.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/playwright-tests.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/spec-driven-testing.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/request-mocking.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/references/video-recording.md
camofox-browser/node_modules/playwright-core/lib/tools/cli-client/skill/SKILL.md
camofox-browser/node_modules/string_decoder/README.md
camofox-browser/node_modules/side-channel-weakmap/CHANGELOG.md
camofox-browser/node_modules/rc/node_modules/strip-json-comments/readme.md
camofox-browser/node_modules/playwright-core/lib/tools/trace/SKILL.md
repos/platform-gitops/tenants/pidoka/prod/zammad/README.md
camofox-browser/node_modules/strip-ansi/readme.md
camofox-browser/node_modules/impit/README.md
camofox-browser/node_modules/impit/CHANGELOG.md
camofox-browser/node_modules/proxy-addr/README.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/intro.md
camofox-browser/node_modules/proxy-addr/HISTORY.md
camofox-browser/node_modules/bytes/Readme.md
camofox-browser/node_modules/bytes/History.md
camofox-browser/node_modules/send/README.md
camofox-browser/node_modules/get-proto/README.md
camofox-browser/node_modules/esutils/README.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/quick-start/first-steps.md
camofox-browser/node_modules/is-standalone-pwa/README.md
camofox-browser/node_modules/ansi-regex/readme.md
camofox-browser/node_modules/get-proto/CHANGELOG.md
camofox-browser/node_modules/send/SECURITY.md
camofox-browser/node_modules/send/HISTORY.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/Contributing/typescript.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/Contributing/fundamental-concepts.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/Contributing/project-goals.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-7.x/Contributing/reporting-issues.md
camofox-browser/node_modules/dot-prop/readme.md
camofox-browser/node_modules/ow/readme.md
camofox-browser/node_modules/send/node_modules/ms/license.md
camofox-browser/node_modules/send/node_modules/ms/readme.md
camofox-browser/node_modules/setprototypeof/README.md
camofox-browser/node_modules/balanced-match/README.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-6.x/intro.md
camofox-browser/node_modules/balanced-match/LICENSE.md
camofox-browser/node_modules/maxmind/README.md
camofox-browser/node_modules/util-deprecate/README.md
camofox-browser/node_modules/util-deprecate/History.md
camofox-browser/node_modules/fs-constants/README.md
camofox-browser/node_modules/inherits/README.md
camofox-browser/node_modules/simple-get/README.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-6.x/Quick Start/first-steps.md
camofox-browser/node_modules/swagger-jsdoc/docusaurus/versioned_docs/version-6.x/Quick Start/cli.md
repos/platform-gitops/platform/infisical-dmz/README.md
camofox-browser/node_modules/file-uri-to-path/README.md
camofox-browser/node_modules/file-uri-to-path/History.md
camofox-browser/node_modules/caniuse-lite/
...(truncated)...

message

An API error occurred: not_in_channel

An API error occurred: not_in_channel

bash

/bin/bash -lc "sed -n '1,260p' PLATFORM_AUFGABEN_KUBE_BOT.md"

/bin/bash -lc "sed -n '1,260p' PLATFORM_AUFGABEN_KUBE_BOT.md"

# Plattformaufgaben — kube-bot Spur

Stand: 2026-06-11
Status: Entwurf / read-only / keine Umsetzung

## Fokus kube-bot

- K3s Plattform-Runtime
- Argo CD / GitOps
- Namespaces / Mandantentrennung
- Ingress / DMZ-Exposure
- NetworkPolicies
- Cluster-/Storage-Risiken aus Kubernetes-Sicht

## P0 — Sofort zu klärende Plattformrisiken

### 1. DMZ-Exposure administrativer Dienste prüfen

Bekannte/zu prüfende Dienste:
- Argo CD: `argocd.cattaro.eu` -> K3s/Ingress
- Kubernetes Dashboard: Namespace `kubernetes-dashboard`, NodePort sichtbar in Inventur
- Portainer: Namespace `portainer`, NodePort/ServiceLB sichtbar
- Longhorn UI: Namespace `longhorn-system`
- Nginx Proxy Manager UI auf Reverse Proxy `192.168.20.20:81`
- später Infisical: bevorzugt nicht in DMZ, sondern Synology/Intranet-Pilot

Ziel:
- keine breit öffentliche Admin-UI
- Zugriff nur Intranet/VPN/ZTNA/IP-Allowlist
- dokumentierte Proxy-/Firewall-Regeln
- klare Owner je Admin-Dienst

### 2. Argo CD Risikostand

Ist-Zustand aus Inventur:
- Argo CD läuft in `infra-argocd`
- mehrere Applications nutzen Project `default`
- einige Apps melden `Unknown`, u.a. wegen Git-Auth-Problemen
- Mandantentrennung über AppProjects noch nicht sauber sichtbar

Risiko:
- Default-Project kann zu breit sein
- Mandanten-Apps und Platform-Apps sind nicht ausreichend getrennt
- Git-Auth/Token-Thema passt direkt zur Infisical-/Secrets-Roadmap

Ziel:
- `platform-*` AppProjects
- `tenant-cattaro`
- `tenant-pidoka` / `tenant-heckenfels` oder sauberer Firmen-/Mandantenname festlegen
- keine Mandantenproduktion im Argo-CD-Default-Project

### 3. K3s / Node / Longhorn Risiken

Bekannt:
- 2 Nodes: `192.168.20.40` control-plane, `192.168.20.45` worker
- K3s-Versionen uneinheitlich: v1.28.4 vs v1.29.3
- Longhorn 3 Replicas bei nur 2 Nodes -> dauerhaft degraded
- Backup Target für Longhorn war leer/nicht verfügbar

Ziel:
- Backup/Restore vor Storage-Änderungen klären
- K3s Upgrade-Pfad definieren
- Longhorn Replica-Konzept festlegen
- dritter Node bzw. Intranet-Management-Node planen

## P1 — Zielstruktur GitOps / Mandanten

### Namespaces Zielbild

Platform:
- `platform-argocd`
- `platform-ingress`
- `platform-secrets`
- `platform-monitoring`
- `platform-logging`
- `platform-backup`
- `platform-storage`

Mandanten:
- `tenant-cattaro-stage`
- `tenant-cattaro-prod`
- `tenant-pidoka-stage` oder `tenant-heckenfels-stage`
- `tenant-pidoka-prod` oder `tenant-heckenfels-prod`

Offene Entscheidung:
- Mandantenname für heckenfels.com/Pidoka sauber festlegen: `pidoka` vs `heckenfels`.

### Argo CD AppProjects Zielbild

Platform:
- `platform-core`
- `platform-network`
- `platform-security`
- `platform-observability`

Tenant:
- `tenant-cattaro`
- `tenant-pidoka` / `tenant-heckenfels`

Grundregeln:
- Tenant-Projekte dürfen nur eigene Namespaces deployen.
- Cluster-scoped Ressourcen nur Platform-Projekten erlauben.
- Repos pro Projekt begrenzen.
- Produktionssyncs mit klarer Approval-Regel.

### GitOps Repo-Struktur — Vorschlag

Variante A: ein Plattform-Repo mit klaren Verzeichnissen

```text
platform-gitops/
  clusters/
    dmz-k3s/
      platform/
      tenants/
        cattaro/
        pidoka/
  projects/
    platform-core/
    tenant-cattaro/
    tenant-pidoka/
  apps/
    platform/
    tenants/
  charts/
  docs/
```

Variante B: getrennte Repos

```text
platform-gitops-infra/
tenant-cattaro-gitops/
tenant-pidoka-gitops/
```

Empfehlung:
- Kurzfristig Variante A wegen kleiner Umgebung und besserer Übersicht.
- Später bei echten DevSecOps-Teams ggf. Mandanten-/Team-Repos trennen.

## P1 — DevSecOps Request Templates

Benötigte Templates:
- Service-Onboarding
- Namespace/AppProject Request
- Secret/Infisical Request
- Ingress/DNS Request
- Storage/PVC Request
- Backup/Restore Request
- Production Change Request
- Incident Report / Post-Incident Review

## Nächste kube-bot Schritte

1. DMZ-Exposure-Matrix aus vorhandener Inventur detaillieren.
2. Argo-CD-AppProject-Zieldefinition ausarbeiten.
3. GitOps-Repo-Struktur als konkreten Vorschlag formulieren.
4. Request-Templates als Markdown-Entwürfe erstellen.

Keine Umsetzung ohne explizites OK.

## Entscheidung — Mandantenname Pidoka

Entscheidung durch Mislav am 2026-06-11:
- Für heckenfels.com/Pidoka-Bereich wird `pidoka` als Mandantenname verwendet.

Standard:
- Namespaces: `tenant-pidoka-stage`, `tenant-pidoka-prod`
- Argo-CD-AppProject: `tenant-pidoka`
- Infisical-Projekt: `tenant-pidoka`
- Labels: `tenant: pidoka`, `owner: pidoka`

Begründung:
- Pidoka ist die organisatorische/rechtliche Einheit; heckenfels.com ist Domain-/Service-Kontext.

## P0.1 Ergebnis — DMZ-Exposure administrativer Dienste

Stand: 2026-06-11, read-only geprüft durch kube-bot.

### Befund

Administrativ relevante Dienste sind innerhalb der DMZ direkt über NodePorts/LoadBalancer-Ports auf beiden K3s-Nodes erreichbar:

- Portainer UI
  - Service: `portainer/portainer`
  - Type: `LoadBalancer`
  - IPs: `192.168.20.40`, `192.168.20.45`
  - Ports: `30777/http`, `30779/https`, `30776/edge`
  - Test: Ports offen, UI liefert HTTP 200

- Kubernetes Dashboard
  - Service: `kubernetes-dashboard/kubernetes-dashboard`
  - Type: `NodePort`
  - Port: `31351/https`
  - Test: Port offen, UI liefert HTTP 200

- Keycloak
  - Service: `keycloak/keycloak`
  - Type: `LoadBalancer`, EXTERNAL-IP pending, aber NodePort `32184/http`
  - Test: Port offen, UI liefert HTTP 200
  - Zusätzlich `svclb-keycloak` war in früherer Inventur auffällig/pending.

- Argo CD
  - Service: `infra-argocd/argocd-server` ClusterIP
  - Ingress: `argocd.cattaro.eu` über Traefik
  - Traefik LoadBalancer: `192.168.20.40/45`, NodePorts `31797/http`, `30508/https`
  - Extern über `https://argocd.cattaro.eu` erreichbar, HTTP 200.

- Longhorn UI
  - Service: `longhorn-system/longhorn-frontend`
  - Type: ClusterIP
  - Kein direkter NodePort/Ingress gefunden.
  - Bewertung: besser als Portainer/Dashboard; weiterhin intern schützen.

### Risiko

In einer DMZ sind direkt erreichbare Admin-UIs riskant, selbst wenn sie nur intern/über Firewall erreichbar sind. Besonders kritisch:

1. Portainer: Container-/Kubernetes-Verwaltung, potentiell hoher Impact.
2. Kubernetes Dashboard: direkter Cluster-Admin-/Token-Bezug möglich.
3. Argo CD: Deployment-Kontrolle; sollte langfristig Management-Zone/Intranet werden.
4. Keycloak: Identitätsdienst, öffentlich/interner Scope muss geklärt werden.

### Empfohlene Maßnahmen ohne direkte Umsetzung

P0-a:
- Mit OPNsense/Nginx Proxy Manager abgleichen, welche dieser Ports aus welchen Netzen erreichbar sind.
- Extern/Internet darf kein direkter Zugriff auf NodePorts bestehen.

P0-b:
- Kubernetes Dashboard nicht per NodePort offen halten; bevorzugt nur temporär via `kubectl proxy`/Port-forward/VPN oder intern streng begrenzt.

P0-c:
- Portainer Zugriff auf VPN/ZTNA/Intranet/IP-Allowlist begrenzen; Edge-Port 30776 prüfen, ob benötigt.

P0-d:
- Argo CD UI/API Zugriff einschränken; langfristig in Intranet/Management-Zone ziehen.

P0-e:
- Keycloak Scope klären: produktiver IdP vs Legacy/Test. Falls nicht benötigt, Exposition reduzieren.

### Keine Änderungen durchgeführt

Alle Checks waren read-only. Keine Services, Ingresses, Firewall-Regeln oder Deployments wurden geändert.

## P0.2 Ergebnis — Proxy-/DMZ-Sicht und Backup-/Intranet-Grenze

Stand: 2026-06-11, read-only geprüft.

### Proxy Host 192.168.20.20 / raspi

Host-/Port-Sicht:
- `80/tcp`, `443/tcp`: Nginx Proxy Manager Frontend
- `81/tcp`: Nginx Proxy Manager Management UI
- `8000/tcp`, `9000/tcp`: Portainer/Portainer Agent Docker-Ports auf dem Proxyhost

Risiko:
- Nginx Proxy Manager UI (`81`) und Portainer (`9000/8000`) sind Management-Oberflächen auf dem Reverse-Proxy-Host.
- Diese sollten nicht öffentlich erreichbar sein und möglichst nur über Intranet/VPN/ZTNA/IP-Allowlist zugänglich sein.

/bin/bash -lc "sed -n '1,260p' SESSION_HANDOFF.md"

/bin/bash -lc "sed -n '1,260p' SESSION_HANDOFF.md"

# SESSION_HANDOFF — kube-bot

Stand: 2026-06-14 09:53 UTC

## Aktueller Zustand
- IT15 ist Management-Ziel.
- One-Node-K3s auf IT15 läuft.
- Neues Argo CD auf IT15 läuft im Namespace `argocd`, Service `argocd-server`, bewusst nur `ClusterIP`/nicht exponiert.
- Bestehendes DMZ-Argo-CD bleibt unverändert bis Parallelbetrieb + Rollback-Gate erfolgreich sind.
- Infisical auf IT15 läuft lokal in Docker/WSL; API erreichbar unter `http://192.168.1.121:8088`.
- Infisical Backup/Restore-Gate war grün.
- Keine Secretwerte werden in Slack/Logs ausgegeben.

## Infisical Stand
- Fachliche Ziel-Organisation für Cattaro-Betrieb: `cattaro_gmbh`.
- `Admin Org` ist nicht mehr Default/Fachgrenze für Cattaro-Infrastruktur.
- Runtime-Variablen aktuell vorhanden:
  - `INFISICAL_CLIENT_ID` gesetzt.
  - `INFISICAL_AUTH_KEY` gesetzt.
- Universal Auth Login mit aktueller Cattaro-Client-ID erfolgreich getestet am 2026-06-14 09:52 UTC.
- Token wurde empfangen, aber nicht ausgegeben.
- `/api/v1/projects` liefert genau 1 sichtbares Projekt:
  - Name: `platform-kubernetes`
  - Slug: `platform-kubernetes-lk-mr`
  - ID: `c5e8661f-4b7a-43e1-80b0-8674f30950dc`
- `/api/v2/projects` existiert auf dieser Instanz nicht / 404.

## Konzeptentscheidung Mandanten / Fachanwendungen
- Cattaro GmbH wird als eigene fachliche Grenze modelliert.
- Externe Mandanten werden später separat modelliert.
- Zielmodell:
  - Infisical: Org `cattaro_gmbh`; Projekt `platform-kubernetes` für Cattaro-Platform/Kubernetes; später `tenant-cattaro` oder app-/mandantenspezifische Projekte nach Bedarf.
  - Argo CD: Platform-AppProjects (`platform-core`, `platform-security`, `platform-observability`) und Tenant-AppProject `tenant-cattaro`.
  - Kubernetes: Platform-Namespaces getrennt von Fachanwendungs-Namespaces, z.B. `platform-argocd`, `platform-secrets`, `tenant-cattaro-stage`, `tenant-cattaro-prod`.
- Keine mandantenübergreifenden Machine Identities.
- Keine globalen Tokens in Argo CD oder Workloads.
- Produktiv-/Stage-/Dev-Identities strikt trennen.
- Konzeptdatei aktualisiert:
  - `/home/node/.openclaw/workspace/INFISICAL_ARGO_K3S_KONZEPT.md`

## Guardrails
- Kein DB-Bootstrap als nächster Schritt.
- DB-Bootstrap nur letzte Option, mit frischem Backup/Restore-Gate und explizitem OK von Mislav.
- Keine schreibenden Infisical-Änderungen ohne explizites OK.
- Keine Argo-CD Credential-Rotation ohne explizites OK.
- Keine Änderungen an DMZ-K3s ohne explizites OK.
- Secrets/Tokens/kubeconfigs niemals im Klartext posten.

## Nächste sichere Schritte
1. Lesend weiter prüfen, welche Environments/Secrets-Metadaten im Projekt `platform-kubernetes` vorhanden sind, ohne Secretwerte auszugeben.
2. Minimalen Zielpfad für kube-bot/Argo-CD Credentials festlegen.
3. Danach mit OK: Argo-CD Admin-Credential rotieren und direkt in Infisical speichern.
4. Danach mit OK: DMZ-K3s mit eingeschränktem Pilot-ServiceAccount/RBAC an IT15-Argo-CD anbinden.
5. Danach Pilotdeployment für unkritische Cattaro-App in `tenant-cattaro-stage`.

## Wichtige Pfade / IDs
- Plan: `/home/node/.openclaw/workspace/ARGOCD_IT15_INFISICAL_PIDOKA_PLAN.md`
- Handoff: `/home/node/.openclaw/workspace/SESSION_HANDOFF.md`
- Konzept: `/home/node/.openclaw/workspace/INFISICAL_ARGO_K3S_KONZEPT.md`
- IT15: `Misla@192.168.1.121`
- Infisical app path: `/opt/infisical`
- Infisical backup grün: `/root/infisical-backups/backup-20260613-080228`

## Ergänzung — Zielkorrektur und offene Aufgaben (2026-06-15 08:34 UTC)

- SSH ist jetzt als Zugriffspfad für den operativen DMZ-K3s-Kontext vorgesehen.
- Ziel bleibt: IT15/Intranet-Argo-CD steuert Deployments in den operativen DMZ-K3s-Cluster.
- Die Dummy-Testanwendung darf nicht auf dem IT15-Management-K3s verbleiben; sie ist als Pilot für den DMZ-Zielcluster zu verwenden.
- Vor dem Pilotdeployment ist read-only zu prüfen, ob und wo die irrtümliche Dummy-App auf IT15 existiert, damit sie später nach explizitem OK sauber entfernt oder ignoriert werden kann.
- Zusätzlich offene Secret-Aufgabe: kube-bot/OpenClaw SSH-Private-Keys sollen in Infisical gesichert werden, weil lokale SSH-Keys nach OpenClaw-Updates verloren gehen können.
- Für SSH-Key-Sicherung gilt: keine Private-Key-Inhalte in Slack/Logs; Ablage nur über sicheren Infisical-Write-Pfad und nur nach explizitem OK.

## Demo Deployment Status — 2026-06-15 12:36 UTC

- SSH/sudo Zugriff auf DMZ Control-Plane `kube-bot@192.168.20.40` funktioniert.
- IT15 Management-K3s und Argo CD sind gesund.
- IT15 kann DMZ Kubernetes API `192.168.20.40:6443` erreichen.
- Pilot-Namespace im DMZ-Cluster angelegt: `tenant-cattaro-stage`.
- Restricted Argo CD ServiceAccount im DMZ-Cluster angelegt: `tenant-cattaro-stage/argocd-demo-manager`.
- IT15 Argo CD Zielcluster-Secret registriert für DMZ-Cluster, beschränkt auf Namespace `tenant-cattaro-stage`.
- Demo-Application in IT15 Argo CD: `argocd/demo-guestbook-cattaro-stage`.
- Quelle: `https://github.com/argoproj/argocd-example-apps.git`, Pfad `guestbook`.
- Ziel: DMZ-Cluster Namespace `tenant-cattaro-stage`.
- Status: `Synced` / `Healthy`.
- Direkte DMZ-Verifikation: `deployment/guestbook-ui` rollout erfolgreich; Service `guestbook-ui` intern per curl erreichbar.

Hinweise:
- Kein Ingress/Public Exposure für die Demo-App angelegt.
- RBAC für den Pilot ist namespace-weit administrativ plus minimale Discovery-Rechte, aber nicht cluster-admin.
- Tokens/Secrets wurden nicht in Slack ausgegeben.

## SSH-Zugangsmerker — 2026-06-15 13:00 UTC

- Aktuelle OpenClaw Runtime: User `node`, Host/Container `0e9d9d0b8619`.
- Lokaler SSH-Key: `/home/node/.ssh/kube-bot-it15-ed25519`.
- Funktionierender DMZ-Control-Plane-Zugang: `kube-bot@192.168.20.40` mit `-i ~/.ssh/kube-bot-it15-ed25519`.
- Auf `192.168.20.40` funktioniert `sudo kubectl --kubeconfig=<redacted> ...`.
- Nicht verwenden: `sudo KUBECONFIG=<redacted> kubectl ...`, weil sudo das Setzen von `KUBECONFIG` blockiert.
- IT15 `Misla@192.168.1.121` ist aus aktueller Runtime derzeit nicht per SSH erreichbar (`Permission denied`); User/Key muss bestätigt oder neu eingerichtet werden.
- Keine SSH-Private-Key-Inhalte in Slack oder Markdown dokumentieren.

## IT15 SSH-Korrektur — 2026-06-15 14:15 UTC

- Korrektes IT15 SSH-Ziel aus OpenClaw Runtime: `Misla@192.168.1.121`.
- Korrektes Kommandomuster: `ssh -i /home/node/.ssh/kube-bot-it15-ed25519 Misla@192.168.1.121`.
- IT15 ist Windows; Linux/K3s-Kontext läuft in WSL Distribution `Ubuntu`.
- Korrektes WSL-Kommandomuster: `ssh -i /home/node/.ssh/kube-bot-it15-ed25519 Misla@192.168.1.121 "wsl.exe -d Ubuntu -e bash -lc '<command>'"`.
- Verifiziert: IT15 Management-K3s `it15-mgmt` Ready, Argo CD Pods Running.
- ArgoCD Apps gefunden:
  - `demo-guestbook-cattaro-stage`: dest `https://192.168.20.40:6443`, namespace `tenant-cattaro-stage`, `Synced/Healthy` — korrektes DMZ-Ziel.
  - `guestbook`: dest `https://kubernetes.default.svc`, namespace `tenant-cattaro-stage`, `Synced/Healthy` — lokale/Intranet-App, später nach explizitem OK entfernen.

## Infisical Recovery-Ablage — kube-bot SSH Keys — 2026-06-15 14:29 UTC

- SSH-Recovery-Secrets liegen in Infisical:
  - Projekt: `platform-kubernetes` (`c5e8661f-4b7a-43e1-80b0-8674f30950dc`)
  - Environment: `prod`
  - Pfad: `/bots/kube-bot/ssh`
- Secret-Namen: `SSH_KEY_IT15_PRIVATE`, `SSH_KEY_IT15_PUBLIC`, `SSH_KEY_IT15_FINGERPRINT`, `SSH_HOST_IT15`, `SSH_KEY_IT15_LOCAL_PATH`, `SSH_HOST_DMZ_CONTROL_PLANE`, `SSH_HOST_DMZ_WORKER`.
- Fingerprint: `SHA256:v1vAeRvbpSAkVQe2kTdjZjwNexaFJ59XWt8+QlOXgmE`.
- Recovery: Key aus Infisical lesen -> `/home/node/.ssh/kube-bot-it15-ed25519` schreiben -> `chmod 600` -> Fingerprint prüfen -> SSH testen.
- Verification 2026-06-15 14:29 UTC: Infisical-readback in temporärer Datei + SSH-Probe auf IT15 erfolgreich; temporäre Datei gelöscht.
- Niemals Private-Key-Inhalte ausgeben.

## Ergänzung Infisical — DMZ SSH Key-Namenssatz — 2026-06-15 14:35 UTC

- DMZ-spezifische SSH-Secrets ergänzt im Pfad `platform-kubernetes/prod:/bots/kube-bot/ssh`:
  - `SSH_KEY_DMZ_PRIVATE`, `SSH_KEY_DMZ_PUBLIC`, `SSH_KEY_DMZ_FINGERPRINT`, `SSH_KEY_DMZ_LOCAL_PATH`, `SSH_HOST_DMZ_CONTROL_PLANE`, `SSH_HOST_DMZ_WORKER`.
- Das Keymaterial ist aktuell identisch mit dem OpenClaw/kube-bot Key für IT15, aber unter separaten DMZ-Namen abgelegt, damit Recovery/Automation nicht an IT15-Namen hängt.
- Verification: Infisical-readback + temporärer SSH-Test auf `kube-bot@192.168.20.40` erfolgreich; temporäre Datei gelöscht.

## SSH Verifikation — DMZ Worker `192.168.20.45` — 2026-06-15 15:03 UTC

- `kube-bot@192.168.20.45` funktioniert mit `/home/node/.ssh/kube-bot-it15-ed25519`.
- sudo NOPASSWD funktioniert.
- Host meldet `mini-it13-02`.
- Key ist über Infisical DMZ-Namenssatz dokumentiert: `platform-kubernetes/prod:/bots/kube-bot/ssh`.

## SSH Verifikation — Nginx Proxy Host `192.168.20.20` — 2026-06-15 15:14 UTC

- `kube-bot@192.168.20.20` funktioniert mit `/home/node/.ssh/kube-bot-it15-ed25519`.
- sudo NOPASSWD funktioniert.
- Host meldet `raspi`.
- Alter Authorized-Key-Kommentar `kube-bot@openclaw-k3s-diagnostics` wurde entfernt; aktueller Key `kube-bot@openclaw-it15-20260614` bleibt.
- Backup der ursprünglichen `authorized_keys` wurde auf dem Zielhost angelegt.

## Ergänzung Infisical — Nginx/Raspi SSH Key-Namenssatz — 2026-06-15 15:16 UTC

- Nginx/Raspi-spezifische SSH-Secrets ergänzt im Pfad `platform-kubernetes/prod:/bots/kube-bot/ssh`:
  - `SSH_KEY_NGINX_PRIVATE`, `SSH_KEY_NGINX_PUBLIC`, `SSH_KEY_NGINX_FINGERPRINT`, `SSH_KEY_NGINX_LOCAL_PATH`, `SSH_HOST_NGINX_PROXY`.
- Ziel: `kube-bot@192.168.20.20`.
- Das Keymaterial ist aktuell identisch mit dem OpenClaw/kube-bot Key, aber unter separaten Nginx-Namen abgelegt.
- Verification: Infisical-readback + temporärer SSH-Test auf `kube-bot@192.168.20.20` erfolgreich; temporäre Datei gelöscht.

## Arbeitsregel ergänzt — Proaktive Schlussfolgerungen — 2026-06-15 15:30 UTC

- Kube-bot soll nach Aktivitäten proaktiv Schlussfolgerungen ziehen, sichere Folgearbeiten erledigen, Merker aktualisieren und nächste Schritte empfehlen.
- Diese Regel gilt allgemein, nicht nur für SSH-Zugänge.
- Grenze bleibt: riskante/schreibende/destructive Infrastruktur-, Cluster-, Firewall-, Secret- oder Deployment-Aktionen nur mit explizitem OK von Mislav.

## Read-only Migrationsinventur — ArgoCD/Mandanten — 2026-06-15 15:45 UTC

- Migrationsmatrix erstellt: `/home/node/.openclaw/workspace/inventory/argocd-mandanten-migrationsmatrix-20260615.md`.
- Rohdaten abgelegt unter: `/home/node/.openclaw/workspace/inventory/migration-20260615/`.
- Ergebnis: IT15-ArgoCD ist Zielsystem; DMZ-ArgoCD `infra-argocd` verwaltet aktuell `n8n`, `hf-mautic`, `hf-espocrm`, `suitecrm`, `apps`.
- Pilot-App `demo-guestbook-cattaro-stage` läuft auf DMZ, aber noch im IT15-ArgoCD Project `default`; nächster sauberer Mandantenmodell-Schritt ist Überführung ins Project `tenant-cattaro`.
- Empfohlene erste echte App-Migration: `hf-n8n`, nach read-only Detailcheck zu Helm-Werten, Secrets-Metadaten, PVC/Backup und Ingress.
- Keine Secrets ausgegeben, keine Cluster-Änderungen durchgeführt.

## Mandanten-Pilot IT15 ArgoCD — 2026-06-15 15:48 UTC

- Freigegeben durch Mislav: Demo-App in Mandantenmodell überführen.
- Änderung durchgeführt:
  - IT15 ArgoCD AppProject `tenant-cattaro` um Destination `https://192.168.20.40:6443` / Namespace `tenant-cattaro-stage` erweitert.
  - Application `demo-guestbook-cattaro-stage` von Project `default` nach `tenant-cattaro` verschoben.
- Verifikation:
  - IT15 ArgoCD: `demo-guestbook-cattaro-stage` ist `Synced/Healthy`, Project `tenant-cattaro`.
  - DMZ-K3s: `tenant-cattaro-stage/guestbook-ui` Deployment/Service/Pod laufen weiter; Pod auf Worker `mini-it13-02`.
- Roh-/Verify-Ausgabe: `/home/node/.openclaw/workspace/inventory/migration-20260615/demo-project-move-verification.txt`.
- Schlussfolgerung: Mandanten-AppProject-Modell funktioniert grundsätzlich für IT15-ArgoCD -> DMZ-K3s.
- Nächster empfohlener Schritt: read-only Detailcheck für erste echte Migration `hf-n8n` (altes DMZ-ArgoCD -> IT15 ArgoCD / te
...(truncated)...

/bin/bash -lc "sed -n '1,260p' TOMORROW_DMZ_INFISICAL.md"

/bin/bash -lc "sed -n '1,260p' TOMORROW_DMZ_INFISICAL.md"

# Morgen: DMZ Infisical Wiedereinstieg

## Ziel
DMZ-Infisical sicher bootstrappen, ohne Firewall-Öffnung oder Public Exposure.

## Startzustand
- ArgoCD grün: `platform-infisical-dmz`, `platform-argocd-projects`, `demo-guestbook-cattaro-stage`.
- DMZ Namespace `platform-infisical` grün.
- Infisical `/api/status`: `Ok`.
- Service nur `ClusterIP`.

## Reihenfolge
1. Status erneut verifizieren.
2. Temporären Port-Forward öffnen.
3. Admin-Erstzugang durchführen.
4. Initial-Secrets/Recovery sichern.
5. Backup/Restore-Konzept für PostgreSQL/PVC festlegen.
6. Danach Operator/Secret-Sync für `n8n`.

## Wichtig
- Keine Secretwerte in Slack/Markdown.
- Kein Ingress/Public Exposure für Bootstrap.
- Keine Cluster-Änderungen ohne explizites OK, außer read-only/status.

/bin/bash -lc "sed -n '1,260p' backup-plans/longhorn-restore-return-path-addendum.md"

/bin/bash -lc "sed -n '1,260p' backup-plans/longhorn-restore-return-path-addendum.md"

# Longhorn Restore-Test Addendum — Synology Return Path

Stand: 2026-06-09 12:18 UTC

## Erkenntnis
Longhorn sieht den Backupstand `backup-e4f3dcd9692e4f50` aktuell im bestehenden BackupTarget `/srv/longhorn-backup-staging`. Ein Restore daraus beweist den Longhorn-Restore aus dem DMZ-Staging, aber noch nicht den Rückweg aus der DiskStation-Kopie.

## Empfohlene Phasen

### Phase A — Restore aus aktuellem DMZ-Staging
Ziel: Prüfen, ob Longhorn aus dem aktuellen BackupTarget ein Test-Volume wiederherstellen kann.

Scope:
- isolierter Namespace, z. B. `restore-test-longhorn`
- Test-PVC/Test-Pod
- nur Mount/Dateisichtbarkeit
- keine App-Integration
- keine produktiven PVCs

Braucht explizites OK, weil Cluster-Schreibaktion.

### Phase B — Rückweg aus Synology-Kopie
Ziel: Prüfen, ob die von Synology gehaltene Kopie wieder als Longhorn-Backupquelle nutzbar gemacht werden kann.

Sicheres Prinzip:
- nicht den aktiven `/srv/longhorn-backup-staging/backupstore` überschreiben
- separate temporäre Restore-Staging-Quelle verwenden, z. B. neuer isolierter Pfad/Mount
- Synology kopiert Backupdaten in diesen separaten Pfad zurück
- Longhorn BackupTarget temporär oder testweise auf diesen separaten Pfad zeigen lassen

Braucht explizites OK, weil mehrere Schreib-/Konfigurationsaktionen beteiligt sind.

## Nicht tun
- Keine Synology-Rückkopie in das aktive Backupstore ohne Review.
- Kein Restore gegen produktive PVCs.
- Kein `--delete`.
- Keine Retention-Löschung.

/bin/bash -lc "sed -n '260,520p' SESSION_HANDOFF.md"

/bin/bash -lc "sed -n '260,520p' SESSION_HANDOFF.md"

- `data-zammad-elasticsearch-master-0`
  - `redis-data-zammad-redis-master-0`
  - `zammad-var-zammad-0`
- GitOps-Commits:
  - `1e74cfd Prepare Zammad Longhorn storage migration`
  - `669b006 Pin Zammad workloads during Longhorn migration`
- Wichtiger Zwischenfall:
  - Erste PostgreSQL-Tar-Copy erzeugte auf dem Ziel ein defektes/0-Byte `PG_VERSION`; erkannt durch PostgreSQL-Startfehler.
  - PostgreSQL-Daten wurden danach kalt mit `cp -a /old/. /new/` neu kopiert; `PG_VERSION=15` und Start anschließend OK.
- Weiterer Befund:
  - Worker `mini-it13-02` konnte alte Bitnami-Image-Tags nicht pullen (`not found`).
  - Zammad Workloads wurden deshalb live und in GitOps per `nodeSelector` auf `mbrkanov-mini-it13` gepinnt, bis Image-Strategie aktualisiert ist.
- Abschlussprüfung:
  - Pods: `zammad-0` 4/4 Running, PostgreSQL/Redis/Elasticsearch/Memcached Running, alle ohne Restarts seit Migration.
  - Laufende Pods mounten die neuen Longhorn-Claims.
  - Longhorn meldet alle vier neuen Volumes `attached` / `healthy`.
  - Datenzählung unverändert: 370 Users, 393 Tickets, 1182 Ticket-Artikel, 4 Organisationen.
  - Letzte Ticket-/Artikel-Updates: 2026-06-17 19:10 UTC.
  - Extern: `https://service.heckenfels.com/` HTTP 200.
  - ArgoCD IT15: `pidoka-hf-zammad` und `pidoka-hf-zammad-secrets` beide `Synced/Healthy` auf Revision `669b0061283f5f7c3ccba9594bcadb14a9db38dd`.
- Empfehlung:
  - Alte local-path PVCs mindestens über eine Beobachtungsphase behalten.
  - Als nächstes Image-Tags/Registry-Strategie für die alten Bitnami-Images bereinigen, damit der nodeSelector wieder entfernt und Scheduling-Flexibilität wiederhergestellt werden kann.

## Altes ArgoCD Repo Audit — 2026-06-15 19:15 UTC

- Audit gestartet nach Mislavs Hinweis auf mögliche Passwörter/Tokens und uneinheitliche ArgoCD-YAML-Struktur.
- Repo geklont: `GitMasterOne/ArgoCD`, Branch `main`, Commit `8882e3c3a9f0414c0fa9f22772a798f1c2be8155`.
- Audit-Dokument: `/home/node/.openclaw/workspace/audits/argocd-repo-20260615/README.md`.
- Befund:
  - Apps sind uneinheitlich modelliert: App-of-apps, externes Helm Chart, lokale Charts, inline `values`, `valuesObject`, `valueFiles`.
  - Passwort-Verdachtsstellen in `espocrm/values*.yaml` und `charts/suitecrm/values.yaml`; keine Secretwerte in Summary ausgegeben.
  - `n8n` ist sauberster erster Migrationskandidat: externes Helm Chart, Secrets über `n8n-secret` referenziert, PVC Longhorn 5Gi, Ingress `n8n.heckenfels.com`.
- Achtung: Eine erste Live-Secret-Abfrage gab Base64-Werte aus; die persistente Datei wurde sofort sanitisiert und enthält nur Secret-/Key-Namen. Künftig bei Secrets nur JSON/Python-Auswertung mit Key-Namen nutzen, niemals `.data` roh ausgeben.
- Empfehlung: altes Repo nicht direkt reorganisieren; App-für-App neu in `platform-gitops` modellieren. Nächster Schritt: n8n-Migrationsmanifest in `platform-gitops` vorbereiten, aber Cutover/Synchronisation nur mit explizitem OK.

## Vertiefung altes ArgoCD Repo — Git-History Scan — 2026-06-15 19:26 UTC

- Git-History Scan ergänzt: `/home/node/.openclaw/workspace/audits/argocd-repo-20260615/git-history-secret-scan-summary.md`.
- 174 Commits gescannt, 102 maskierte eindeutige Verdachtsfunde.
- Keine GitHub PATs/Private Keys/JWTs gefunden, aber viele Passwort-/Secret-Key-Felder in aktuellen und historischen Dateien.
- Konsequenz: altes Repo samt History als secret-belastet behandeln; nicht in neues Repo übernehmen; betroffene Passwörter perspektivisch rotieren.
- Normalisierungsziel für neues `platform-gitops` dokumentiert: pro App `application.yaml`, `values.yaml`, `external-secrets.yaml`, optional `kustomization.yaml`, `README.md`; keine inline Secretwerte; keine History-Übernahme.
- Nächster sicherer Schritt: für `n8n` Zielstruktur in `platform-gitops` vorbereiten und Secretstrategie definieren. Noch kein Sync/Cutover ohne explizites OK.

## DMZ Infisical via IT15 ArgoCD deployed — 2026-06-15 20:56 UTC

- Architekturentscheidung umgesetzt: DMZ-lokales Infisical statt Firewall-Öffnung DMZ -> IT15.
- GitOps Repo `GitMasterOne/platform-gitops` aktualisiert:
  - Commit `06a7f5c`: `Add DMZ Infisical platform app`
  - Commit `58d807d`: `Allow guestbook demo repo for Cattaro tenant project`
- Neue ArgoCD Application: `platform-infisical-dmz` im Project `platform`.
- Helm Chart: `infisical-standalone` `1.9.0`, Image `infisical/infisical:v0.158.0`.
- Namespace: `platform-infisical`.
- Exposure: nur `ClusterIP`, kein Ingress, kein Public/NPM-Exposure.
- Storage: Longhorn PVCs:
  - PostgreSQL `8Gi`: `data-postgresql-0`
  - Redis `2Gi`: `redis-data-redis-master-0`
- Initial runtime secrets wurden direkt im DMZ-K3s erstellt und NICHT ins Git geschrieben:
  - `infisical-secrets`
  - `postgresql`
  - `redis`
- ArgoCD DMZ Cluster Credential korrigiert:
  - gemeinsamer ServiceAccount `platform-infisical/argocd-dmz-manager`
  - RoleBindings in `platform-infisical` und `tenant-cattaro-stage`
  - ArgoCD Cluster Secret `dmz-k3s-tenant-cattaro-stage` nutzt jetzt den gemeinsamen Token und Namespaces `tenant-cattaro-stage,platform-infisical`
  - temporäres Cluster Secret `dmz-k3s-platform-infisical` wurde gelöscht
- Verification:
  - `platform-infisical` Pods: Infisical/PostgreSQL/Redis Running
  - `/api/status` cluster-intern: `Ok`, `redisConfigured=true`, `inviteOnlySignup=true`
  - IT15 ArgoCD Apps final: `platform-infisical-dmz`, `demo-guestbook-cattaro-stage`, `platform-argocd-projects` alle `Synced/Healthy`
- Auffälligkeit: Infisical-App hatte beim ersten Start 3 Restarts, weil PostgreSQL noch initialisierte. Danach stabil und healthy.
- Nächste Schritte:
  1. Admin-Erstzugang/Bootstrap für DMZ-Infisical klären, vorzugsweise per Port-Forward, nicht öffentlich.
  2. Initial runtime secrets (AUTH_SECRET, ENCRYPTION_KEY, DB/Redis) sicher sichern/Recovery-Konzept festlegen. Aktuell nur in Kubernetes Secrets/PVCs, nicht in Infisical/Markdown.
  3. Backup/Restore-Konzept für DMZ-Infisical PostgreSQL/Longhorn definieren.
  4. Danach Infisical Operator/External Secret Integration für n8n vorbereiten.

## Tagesabschluss / Wiedereinstieg morgen — DMZ Infisical — 2026-06-15 21:39 UTC

### Aktueller verifizierter Zustand

- IT15 ArgoCD:
  - `platform-infisical-dmz`: `Synced / Healthy`
  - `demo-guestbook-cattaro-stage`: `Synced / Healthy`
  - `platform-argocd-projects`: `Synced / Healthy`
- DMZ K3s Namespace: `platform-infisical`
  - Infisical Pod: `1/1 Running`, neuer Pod ohne Restarts beim letzten Check
  - PostgreSQL: `1/1 Running`
  - Redis: `1/1 Running`
  - PVCs: Longhorn `Bound`
- Cluster-interner Healthcheck:
  - `GET http://infisical-infisical-standalone-infisical:8080/api/status`
  - Antwort: `message=Ok`, `redisConfigured=true`, `inviteOnlySignup=true`
- Exposure:
  - Nur `ClusterIP`
  - Kein Ingress
  - Keine Firewall-Öffnung
  - Kein öffentliches/NPM Exposure

### Was heute geändert wurde

- DMZ-lokales Infisical per IT15-ArgoCD eingeführt.
- GitOps Repo `GitMasterOne/platform-gitops`:
  - Commit `06a7f5c`: `Add DMZ Infisical platform app`
  - Commit `58d807d`: `Allow guestbook demo repo for Cattaro tenant project`
- ArgoCD DMZ Cluster Credential korrigiert:
  - ein gemeinsamer namespace-beschränkter ServiceAccount für `tenant-cattaro-stage` und `platform-infisical`
  - keine Cluster-weiten Adminrechte für diesen Flow dokumentiert
- Initial runtime Kubernetes Secrets in `platform-infisical` erzeugt:
  - `infisical-secrets`
  - `postgresql`
  - `redis`
- Keine Secretwerte ins Git oder in Markdown geschrieben.

### Sicherheits-/Betriebsnotizen

- Aktuell ist DMZ-Infisical funktional, aber noch nicht produktionsfertig gebootstrappt.
- Kritischster offener Punkt: Recovery/Backup für Initial-Secrets und PostgreSQL/PVCs.
- Die Initial-Secrets existieren aktuell nur als Kubernetes Secrets im DMZ-Cluster; Werte nicht ausgeben.
- Erstzugang sollte nur temporär per Port-Forward erfolgen, nicht per Ingress/Public Exposure.
- `inviteOnlySignup=true`, also keine offene Registrierung.

### Morgen empfohlene Reihenfolge

1. Kurzstatus prüfen:
   - IT15 ArgoCD Apps `platform-infisical-dmz`, `platform-argocd-projects`, `demo-guestbook-cattaro-stage`
   - DMZ Pods/PVCs in `platform-infisical`
   - `/api/status`
2. Temporären Port-Forward für Mislav öffnen:
   - Von einem erreichbaren Rechner aus per SSH/Kubectl gegen DMZ Control Plane.
   - Ziel: lokaler Browser `http://localhost:<port>` -> Service `infisical-infisical-standalone-infisical:8080`.
   - Kein Firewall-Change, nur laufende Session.
3. Admin-Erstzugang/Bootstrap durchführen.
4. Direkt danach Recovery absichern:
   - Initial-Secrets sicher in IT15-Infisical oder anderem vereinbarten Recovery-Pfad ablegen.
   - Keine Secretwerte in Slack/Markdown posten.
5. Backup-Konzept für DMZ-Infisical festlegen:
   - mindestens PostgreSQL Dump oder Longhorn recurring snapshot/backup
   - Recovery-Probe planen
6. Danach erst Infisical Operator / Secret-Sync für `n8n` vorbereiten.

### Wenn morgen wenig Zeit ist

Minimal sicherer nächster Schritt:
- Nur Status prüfen + Port-Forward erklären/öffnen.
- Bootstrap/Recovery erst machen, wenn Mislav genug Zeit hat.

### Kurzbefehl-Idee für Status morgen

- IT15 ArgoCD App Status via WSL auf IT15.
- DMZ Status via SSH `kube-bot@192.168.20.40` und `/etc/rancher/k3s/k3s.yaml`.

## DMZ Infisical Bootstrap / kube-bot Machine Identity — 2026-06-16 18:33 UTC

- DMZ-Infisical ist temporär via Port-Forward erreichbar unter `http://192.168.20.40:18080`.
- Mislav hat Organisation und Projekt in DMZ-Infisical angelegt.
- DMZ-Infisical Projekt sichtbar für kube-bot:
  - Name: `platform-kubernetes`
  - ID: `d66f3d3b-1484-46f6-8142-f6fc32222b4d`
  - Slug: `platform-kubernetes-pqmd`
- Machine Identity in DMZ-Infisical:
  - Name: `kube-bot`
  - Client-ID: `9d47b9d2-c994-4449-afa1-5bbbf271eda0`
- Client Secret wurde nicht in Slack/Markdown ausgegeben.
- Recovery-/Bootstrap-Secrets liegen in IT15-Infisical:
  - Projekt: `platform-kubernetes` (`c5e8661f-4b7a-43e1-80b0-8674f30950dc`)
  - Environment: `prod`
  - Pfad: `/platform/kube-bot`
  - Secret-Namen: `DMZ_INFISICAL_KUBE_BOT_CLIENT_ID`, `DMZ_INFISICAL_KUBE_BOT_CLIENT_SECRET`, `DMZ_INFISICAL_URL`
- Verification: kube-bot Universal Auth Login gegen DMZ-Infisical erfolgreich; `/api/v1/projects` zeigt `platform-kubernetes`.
- Hinweis: Wunsch-Zielpfad `/platform/infisical/dmz/bootstrap` wurde noch nicht befüllt, weil die verfügbare API-Create-Route encrypted payload erwartet. Aktueller Pfad `/platform/kube-bot` ist funktional und verifiziert.

## Korrektur Tenant-Zuordnung — 2026-06-16 18:53 UTC

- Mislav hat klargestellt:  gehört fachlich zur **PIDOKA GmbH**, nicht zur Cattaro GmbH.
- Für n8n-GitOps ist daher das Ziel-AppProject/der Zielpfad  zu verwenden bzw. entsprechend zu erweitern.
- Bestehender Namespace ist aktuell ; fachliche Zielzuordnung: PIDOKA.

## Korrektur Tenant-Zuordnung — 2026-06-16 18:53 UTC

- Mislav hat klargestellt: n8n gehört fachlich zur **PIDOKA GmbH**, nicht zur Cattaro GmbH.
- Für n8n-GitOps ist daher das Ziel-AppProject/der Zielpfad `tenant-pidoka` zu verwenden bzw. entsprechend zu erweitern.
- Bestehender Namespace ist aktuell `hf-n8n`; fachliche Zielzuordnung: PIDOKA.

## PIDOKA n8n GitOps Vorbereitung — 2026-06-16 19:08 UTC

- Fachliche Korrektur: n8n gehört zur PIDOKA GmbH.
- Bestehendes n8n läuft in DMZ Namespace `hf-n8n` und wird aktuell noch vom alten DMZ-ArgoCD `infra-argocd/n8n` verwaltet.
- IT15-ArgoCD AppProject `tenant-pidoka` erlaubt bereits Zielnamespace `hf-n8n` und Source `8gears.container-registry.com`.
- Neue GitOps-Manifeste wurden im Repo `GitMasterOne/platform-gitops` vorbereitet und gepusht:
  - Commit: `8a58482 Add PIDOKA n8n GitOps migration manifest`
  - `applications/tenants/pidoka/n8n.yaml`
  - `tenants/pidoka/prod/n8n/values.yaml`
  - `tenants/pidoka/prod/n8n/README.md`
- Ziel der neuen App: IT15-ArgoCD Application `pidoka-n8n`, Project `tenant-pidoka`, Destination `https://192.168.20.40:6443`, Namespace `hf-n8n`.
- SyncPolicy der neuen App bewusst vorsichtig: `prune=false`, `selfHeal=false
...(truncated)...

/bin/bash -lc "sed -n '1,260p' backup-plans/longhorn-restore-test-kube-review.md"

/bin/bash -lc "sed -n '1,260p' backup-plans/longhorn-restore-test-kube-review.md"

# Longhorn Restore-Test — kube-bot Review

Stand: 2026-06-09 12:16 UTC

## Ziel
Nachweisen, dass aus dem von Synology gepullten Longhorn-Backupbestand ein nutzbares Test-Volume wiederhergestellt werden kann, ohne produktive PVCs oder Workloads zu verändern.

## Aktuell validiert
- Longhorn BackupTarget: `nfs://192.168.20.40:/srv/longhorn-backup-staging`, `available=true`
- Synology Pull: read-only NFS + `rsync -a --stats --exclude lost+found/`, kein `--delete`
- Letzter Sync: `STATUS=ok`, Source/Target exakt gleich
- Nodes Ready, Longhorn Manager Running
- Staging-Export für Synology: `192.168.13.10(ro,insecure,root_squash)`

## Restore-Test-Prinzip
1. Nicht gegen produktive Namespaces/PVCs testen.
2. Isolierten Namespace verwenden, z. B. `restore-test-longhorn`.
3. Test-PVC aus Longhorn-Backup wiederherstellen.
4. Nur lesenden/harmlosen Test-Pod starten, z. B. BusyBox/Alpine, um Mount und Dateien zu prüfen.
5. Ergebnis dokumentieren: PVC bound, Pod running/completed, erwartete Daten sichtbar.
6. Danach Testressourcen entfernen — Löschung ebenfalls nur mit explizitem OK, weil Cluster-Änderung.

## Wichtige offene Entscheidung vor Ausführung
- Welcher Backupstand wird getestet?
  - Kandidat: Testbackup `backup-e4f3dcd9692e4f50` von Volume `pvc-f6714be0-39b1-47e6-baa2-2e1ae801d907` (`hf-matomo/matomo-pvc`).
- Soll der Restore-Test nur Longhorn-Volume-Mount prüfen oder auch applikationsspezifische Konsistenz?
  - Empfehlung erster Lauf: nur Volume-Restore/Mount/Dateisichtbarkeit, keine App-Integration.

## Nicht ohne explizites OK
- Restore ausführen
- Namespace/PVC/Pod anlegen
- produktive PVCs verändern/überschreiben
- Longhorn Settings, Replica Counts, StorageClasses ändern
- Retention-Pruning oder `--delete`

## Empfehlung
Nächster sinnvoller Schritt ist Review des DiskStation-Restore-Testplans gegen diese Guardrails. Danach Mislav gezielt um OK für einen isolierten Restore-Test bitten, wenn er ihn ausführen möchte.

/bin/bash -lc "rg -n \"2026-06-17|Zammad|Longhorn|morgen|heute|offen|Needs|OK|n8n|Infisical\" -S . --glob '"'!camofox-browser/node_modules/**'"' --glob '"'!repos/**'"'"

/bin/bash -lc "rg -n \"2026-06-17|Zammad|Longhorn|morgen|heute|offen|Needs|OK|n8n|Infisical\" -S . --glob '"'!camofox-browser/node_modules/**'"' --glob '"'!repos/**'"'"

./SOUL.md:10:- Destructive Actions nur nach explizitem OK von Mislav
./backup-plans/longhorn-restore-return-path-addendum.md:1:# Longhorn Restore-Test Addendum — Synology Return Path
./backup-plans/longhorn-restore-return-path-addendum.md:6:Longhorn sieht den Backupstand `backup-e4f3dcd9692e4f50` aktuell im bestehenden BackupTarget `/srv/longhorn-backup-staging`. Ein Restore daraus beweist den Longhorn-Restore aus dem DMZ-Staging, aber noch nicht den Rückweg aus der DiskStation-Kopie.
./backup-plans/longhorn-restore-return-path-addendum.md:11:Ziel: Prüfen, ob Longhorn aus dem aktuellen BackupTarget ein Test-Volume wiederherstellen kann.
./backup-plans/longhorn-restore-return-path-addendum.md:20:Braucht explizites OK, weil Cluster-Schreibaktion.
./backup-plans/longhorn-restore-return-path-addendum.md:23:Ziel: Prüfen, ob die von Synology gehaltene Kopie wieder als Longhorn-Backupquelle nutzbar gemacht werden kann.
./backup-plans/longhorn-restore-return-path-addendum.md:29:- Longhorn BackupTarget temporär oder testweise auf diesen separaten Pfad zeigen lassen
./backup-plans/longhorn-restore-return-path-addendum.md:31:Braucht explizites OK, weil mehrere Schreib-/Konfigurationsaktionen beteiligt sind.
./backup-plans/longhorn-restore-test-kube-review.md:1:# Longhorn Restore-Test — kube-bot Review
./backup-plans/longhorn-restore-test-kube-review.md:6:Nachweisen, dass aus dem von Synology gepullten Longhorn-Backupbestand ein nutzbares Test-Volume wiederhergestellt werden kann, ohne produktive PVCs oder Workloads zu verändern.
./backup-plans/longhorn-restore-test-kube-review.md:9:- Longhorn BackupTarget: `nfs://192.168.20.40:/srv/longhorn-backup-staging`, `available=true`
./backup-plans/longhorn-restore-test-kube-review.md:12:- Nodes Ready, Longhorn Manager Running
./backup-plans/longhorn-restore-test-kube-review.md:18:3. Test-PVC aus Longhorn-Backup wiederherstellen.
./backup-plans/longhorn-restore-test-kube-review.md:21:6. Danach Testressourcen entfernen — Löschung ebenfalls nur mit explizitem OK, weil Cluster-Änderung.
./backup-plans/longhorn-restore-test-kube-review.md:23:## Wichtige offene Entscheidung vor Ausführung
./backup-plans/longhorn-restore-test-kube-review.md:26:- Soll der Restore-Test nur Longhorn-Volume-Mount prüfen oder auch applikationsspezifische Konsistenz?
./backup-plans/longhorn-restore-test-kube-review.md:29:## Nicht ohne explizites OK
./backup-plans/longhorn-restore-test-kube-review.md:33:- Longhorn Settings, Replica Counts, StorageClasses ändern
./backup-plans/longhorn-restore-test-kube-review.md:37:Nächster sinnvoller Schritt ist Review des DiskStation-Restore-Testplans gegen diese Guardrails. Danach Mislav gezielt um OK für einen isolierten Restore-Test bitten, wenn er ihn ausführen möchte.
./win-portproxy-final-8088.ps1:10:if (-not (Get-NetFirewallRule -DisplayName 'Infisical IT15 TCP 8088' -ErrorAction SilentlyContinue)) {
./win-portproxy-final-8088.ps1:11:  New-NetFirewallRule -DisplayName 'Infisical IT15 TCP 8088' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8088 -Profile Any | Out-Null
./wsl-real-restore-infisical.ps1:35:# normalize common Infisical mappings to 8088:8080
./run-final-backup-restore-test.sh:15:sed -n '1,120p' "$LATEST/manifest.txt" | sed -E 's/(PASSWORD|SECRET|KEY|TOKEN|AUTH|ENCRYPTION).*/[REDACTED]/I' || true
./win-check-open-8088.ps1:7:Get-NetFirewallRule -DisplayName '*Infisical*8088*' -ErrorAction SilentlyContinue | Select-Object DisplayName,Enabled,Direction,Action,Profile | Format-Table -AutoSize
./win-check-open-8088.ps1:9:if (-not (Get-NetFirewallRule -DisplayName 'Infisical IT15 TCP 8088' -ErrorAction SilentlyContinue)) {
./win-check-open-8088.ps1:10:  New-NetFirewallRule -DisplayName 'Infisical IT15 TCP 8088' -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8088 -Profile Any | Out-Null
./win-check-open-8088.ps1:12:Get-NetFirewallRule -DisplayName 'Infisical IT15 TCP 8088' | Select-Object DisplayName,Enabled,Direction,Action,Profile | Format-Table -AutoSize
./IDENTITY.md:15:kube-bot führt keine eigenständigen Änderungen aus. Destructive Actions benötigen immer ein explizites OK von Mislav im Chat.
./wsl-fix-infisical-key.ps1:16:enc=secrets.token_hex(16)  # Infisical requires random 16-byte hex string (32 hex chars)
./INFISICAL_ARGO_K3S_KONZEPT.md:1:# Konzeptnotiz — Argo CD + K3s + Infisical
./INFISICAL_ARGO_K3S_KONZEPT.md:8:Argo CD steuert Deployments deklarativ aus Git. Infisical verwaltet Secrets zentral. K3s führt Workloads aus.
./INFISICAL_ARGO_K3S_KONZEPT.md:14:- eigenes Infisical-Projekt oder streng getrennte Infisical-Struktur pro Mandant
./INFISICAL_ARGO_K3S_KONZEPT.md:20:Empfohlene Regel: ein Mandant = ein Argo-CD-AppProject + ein Namespace-Set + ein Infisical-Projekt + eigene Sync-Identity.
./INFISICAL_ARGO_K3S_KONZEPT.md:24:Bestimmte Dienste wie Infisical, Argo CD, Ingress, Monitoring, Logging, Backup, Zertifikatsmanagement oder ggf. Registry/Storage werden mandantenübergreifend bereitgestellt.
./INFISICAL_ARGO_K3S_KONZEPT.md:69:## Infisical Struktur
./INFISICAL_ARGO_K3S_KONZEPT.md:71:### Infisical als Plattformdienst
./INFISICAL_ARGO_K3S_KONZEPT.md:78:### Infisical Projekte
./INFISICAL_ARGO_K3S_KONZEPT.md:101:- pro Mandant eigene Infisical Machine Identity
./INFISICAL_ARGO_K3S_KONZEPT.md:103:- pro Workload eigene ExternalSecret/InfisicalSecret Definition
./INFISICAL_ARGO_K3S_KONZEPT.md:105:- Rotation über Infisical, Reconcile über Operator
./INFISICAL_ARGO_K3S_KONZEPT.md:112:- Infisical Betrieb
./INFISICAL_ARGO_K3S_KONZEPT.md:120:- Zugriff auf eigene Infisical-Projekte
./INFISICAL_ARGO_K3S_KONZEPT.md:143:4. Infisical Projekt tenant-cattaro anlegen.
./INFISICAL_ARGO_K3S_KONZEPT.md:162:   - Mandantenübergreifende Infrastruktur wie Argo CD, Infisical, Ingress, cert-manager, Monitoring, Logging, Backup, Storage.
./INFISICAL_ARGO_K3S_KONZEPT.md:174:- Longhorn ist mit 3 Replicas konfiguriert, aber nur 2 Nodes vorhanden; Volumes dauerhaft degraded.
./INFISICAL_ARGO_K3S_KONZEPT.md:175:- Longhorn Backup Target war leer/nicht verfügbar.
./INFISICAL_ARGO_K3S_KONZEPT.md:180:- Infisical nicht öffentlich verfügbar machen, außer zwingend notwendig und dann nur mit starker Auth/MFA, IP-/VPN-Beschränkung und WAF/Proxy-Härtung.
./INFISICAL_ARGO_K3S_KONZEPT.md:192:- Infisical nur nach Backup/Restore-Konzept und möglichst mit externer/Longhorn-gesicherter Datenbank.
./INFISICAL_ARGO_K3S_KONZEPT.md:201:## Vorbereitende Aufgaben vor Infisical-Produktivbetrieb
./INFISICAL_ARGO_K3S_KONZEPT.md:203:1. Backup-Ziel für Longhorn/Infisical klären.
./INFISICAL_ARGO_K3S_KONZEPT.md:206:4. Longhorn Replica-Konzept für 2 oder 3 Nodes festlegen.
./INFISICAL_ARGO_K3S_KONZEPT.md:207:5. DMZ-Exposure für Argo CD, Infisical, Dashboard, Portainer prüfen.
./INFISICAL_ARGO_K3S_KONZEPT.md:210:8. Infisical-Projekte und Machine Identities mandantenscharf modellieren.
./INFISICAL_ARGO_K3S_KONZEPT.md:227:- Infisical
./INFISICAL_ARGO_K3S_KONZEPT.md:242:## Infisical-Variante
./INFISICAL_ARGO_K3S_KONZEPT.md:246:- Infisical läuft im Intranet.
./INFISICAL_ARGO_K3S_KONZEPT.md:247:- DMZ-Workloads erhalten keine breit berechtigten Infisical-Zugriffe.
./INFISICAL_ARGO_K3S_KONZEPT.md:269:## Ergänzung NAS-/Backup-Sicht: Sync-Richtung Infisical / DMZ
./INFISICAL_ARGO_K3S_KONZEPT.md:271:Wichtiger Architekturpunkt: Viele Secret-Operator-Modelle arbeiten als Pull aus dem Cluster. Wenn der Operator in der DMZ läuft und Infisical im Intranet steht, entsteht technisch DMZ -> Intranet Traffic. Das darf nicht unbewusst oder breit erlaubt werden.
./INFISICAL_ARGO_K3S_KONZEPT.md:278:Fallback-Variante, falls DMZ -> Infisical technisch nötig ist:
./INFISICAL_ARGO_K3S_KONZEPT.md:279:- ausschließlich HTTPS zur konkreten Infisical-Adresse
./INFISICAL_ARGO_K3S_KONZEPT.md:292:Stand: Es gibt aktuell keinen freien Intranet-Node für Infisical/Argo-CD-Management-Zone.
./INFISICAL_ARGO_K3S_KONZEPT.md:305:- Wenn DiskStation-Bot/NAS-Sicht keine harten Einwände hat, Infisical bevorzugt übergangsweise im Intranet auf der DiskStation betreiben.
./INFISICAL_ARGO_K3S_KONZEPT.md:316:- Einschätzung: geeignet als Übergang/Pilot für Infisical, nicht als dauerhafte Plattform-Zentrale.
./INFISICAL_ARGO_K3S_KONZEPT.md:319:- Infisical darf übergangsweise auf der Synology DiskStation im Intranet betrieben werden.
./INFISICAL_ARGO_K3S_KONZEPT.md:320:- Kein öffentlicher Zugriff auf Infisical.
./INFISICAL_ARGO_K3S_KONZEPT.md:328:Diese Übergangslösung ist sicherheitlich besser als Infisical in der DMZ, koppelt aber Secret-Management und NAS/Backup enger. Deshalb nur als Pilot/Übergang nutzen und bewusst klein halten.
./INFISICAL_ARGO_K3S_KONZEPT.md:346:- Erst read-only; Änderungen nur nach explizitem OK.
./INFISICAL_ARGO_K3S_KONZEPT.md:353:- Infisical, Secret-Rotation, Machine Identities, Zugriffspfade, Audit, MFA, Key-Lifecycle.
./INFISICAL_ARGO_K3S_KONZEPT.md:376:- Infisical-Projekte/Environments pro Mandant/App
./INFISICAL_ARGO_K3S_KONZEPT.md:398:- Änderungen nur mit explizitem OK von Mislav oder definiertem Owner
./INFISICAL_ARGO_K3S_KONZEPT.md:408:- secrets-bot: Infisical, Machine Identities, Rotation, Audit
./INFISICAL_ARGO_K3S_KONZEPT.md:413:Kein Bot darf alles. Standard ist lesend/prüfend. Schreibaktionen nur im eigenen Verantwortungsbereich; produktive/destruktive Aktionen nur mit explizitem OK.
./INFISICAL_ARGO_K3S_KONZEPT.md:418:- Infisical-Projekt
./INFISICAL_ARGO_K3S_KONZEPT.md:436:- Entscheidungsprotokolle, Architekturentscheidungen und offene Aufgaben nachhalten
./INFISICAL_ARGO_K3S_KONZEPT.md:443:- keine eigenständige technische Ausführung ohne Owner-OK
./INFISICAL_ARGO_K3S_KONZEPT.md:581:- später secrets-bot: Infisical, Rotation, Machine Identities, Audit
./INFISICAL_ARGO_K3S_KONZEPT.md:594:# Aktualisierung — 2026-06-14 — Organisationsgrenze Infisical
./INFISICAL_ARGO_K3S_KONZEPT.md:597:- Für Cattaro-Infrastruktur und Cattaro-Fachanwendungen wird in Infisical die Organisation `cattaro_gmbh` verwendet.
./INFISICAL_ARGO_K3S_KONZEPT.md:602:## Infisical
./INFISICAL_ARGO_K3S_KONZEPT.md:615:  - bevorzugt eigenes Infisical-Projekt `tenant-<mandant>` innerhalb einer passend verwalteten Organisation, falls Cattaro den Betrieb zentral verantwortet;
./INFISICAL_ARGO_K3S_KONZEPT.md:616:  - alternativ eigene Infisical-Organisation je externem Mandanten, wenn rechtliche/operative Trennung, Audit oder Admin-Delegation das erfordern.
./INFISICAL_ARGO_K3S_KONZEPT.md:649:- Kein globales Infisical-Token in Argo CD oder Workloads.
./INFISICAL_ARGO_K3S_KONZEPT.md:650:- Secrets bleiben in Infisical; Git enthält nur Referenzen/ExternalSecret-Definitionen.
./INFRASTRUCTURE.md:56:- n8n.heckenfels.com → https://192.168.20.40:443
./INFRASTRUCTURE.md:60:- Änderungen nur nach explizitem OK von Mislav pro konkreter Änderung.
./INFRASTRUCTURE.md:87:  - `n8n.heckenfels.com`
./INFRASTRUCTURE.md:98:  - Änderungen nur nach explizitem OK von Mislav
./INFRASTRUCTURE.md:114:- Änderungen über SSH nur nach explizitem OK von Mislav und mit konkretem Scope.
./INFRASTRUCTURE.md:116:- Offene Aufgabe: kube-bot/OpenClaw SSH-Private-Keys sicher in Infisical ablegen, damit sie nach OpenClaw-Updates nicht verloren gehen.
./INFRASTRUCTURE.md:125:- Änderungen an Backup-Konfigurationen nur nach explizitem OK von Mislav.
./INFRASTRUCTURE.md:148:- Betriebsregel bleibt: SSH primär read-only Diagnose; Änderungen nur nach explizitem OK von Mislav.
./INFRASTRUCTURE.md:157:### Infisical Recovery-Ablage — kube-bot SSH Keys — 2026-06-15 14:29 UTC
./INFRASTRUCTURE.md:159:- Infisical Instanz: `http://192.168.1.121:8088`.
./INFRASTRUCTURE.md:172:- Recovery-Prinzip: Private Key aus Infisical lesen, nach `/home/node/.ssh/kube-bot-it15-ed25519` schreiben, `chmod 600`, Fingerprint prüfen, SSH-Test ausführen.
./INFRASTRUCTURE.md:173:- Verifiziert: temporär aus Infisical gelesener Key konnte mit `chmod 600` für SSH auf `Misla@192.168.1.121` genutzt werden. Temporäre Datei wurde gelöscht.
./INFRASTRUCTURE.md:176:### Ergänzung Infisical — DMZ SSH Key-Namenssatz — 2026-06-15 14:35 UTC
./INFRASTRUCTURE.md:178:- Ergänzt im bestehenden Infisical-Pfa
...(truncated)...

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '360,620p'"

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '360,620p'"

360	### Was heute geändert wurde
   361
   362	- DMZ-lokales Infisical per IT15-ArgoCD eingeführt.
   363	- GitOps Repo `GitMasterOne/platform-gitops`:
   364	  - Commit `06a7f5c`: `Add DMZ Infisical platform app`
   365	  - Commit `58d807d`: `Allow guestbook demo repo for Cattaro tenant project`
   366	- ArgoCD DMZ Cluster Credential korrigiert:
   367	  - ein gemeinsamer namespace-beschränkter ServiceAccount für `tenant-cattaro-stage` und `platform-infisical`
   368	  - keine Cluster-weiten Adminrechte für diesen Flow dokumentiert
   369	- Initial runtime Kubernetes Secrets in `platform-infisical` erzeugt:
   370	  - `infisical-secrets`
   371	  - `postgresql`
   372	  - `redis`
   373	- Keine Secretwerte ins Git oder in Markdown geschrieben.
   374
   375	### Sicherheits-/Betriebsnotizen
   376
   377	- Aktuell ist DMZ-Infisical funktional, aber noch nicht produktionsfertig gebootstrappt.
   378	- Kritischster offener Punkt: Recovery/Backup für Initial-Secrets und PostgreSQL/PVCs.
   379	- Die Initial-Secrets existieren aktuell nur als Kubernetes Secrets im DMZ-Cluster; Werte nicht ausgeben.
   380	- Erstzugang sollte nur temporär per Port-Forward erfolgen, nicht per Ingress/Public Exposure.
   381	- `inviteOnlySignup=true`, also keine offene Registrierung.
   382
   383	### Morgen empfohlene Reihenfolge
   384
   385	1. Kurzstatus prüfen:
   386	   - IT15 ArgoCD Apps `platform-infisical-dmz`, `platform-argocd-projects`, `demo-guestbook-cattaro-stage`
   387	   - DMZ Pods/PVCs in `platform-infisical`
   388	   - `/api/status`
   389	2. Temporären Port-Forward für Mislav öffnen:
   390	   - Von einem erreichbaren Rechner aus per SSH/Kubectl gegen DMZ Control Plane.
   391	   - Ziel: lokaler Browser `http://localhost:<port>` -> Service `infisical-infisical-standalone-infisical:8080`.
   392	   - Kein Firewall-Change, nur laufende Session.
   393	3. Admin-Erstzugang/Bootstrap durchführen.
   394	4. Direkt danach Recovery absichern:
   395	   - Initial-Secrets sicher in IT15-Infisical oder anderem vereinbarten Recovery-Pfad ablegen.
   396	   - Keine Secretwerte in Slack/Markdown posten.
   397	5. Backup-Konzept für DMZ-Infisical festlegen:
   398	   - mindestens PostgreSQL Dump oder Longhorn recurring snapshot/backup
   399	   - Recovery-Probe planen
   400	6. Danach erst Infisical Operator / Secret-Sync für `n8n` vorbereiten.
   401
   402	### Wenn morgen wenig Zeit ist
   403
   404	Minimal sicherer nächster Schritt:
   405	- Nur Status prüfen + Port-Forward erklären/öffnen.
   406	- Bootstrap/Recovery erst machen, wenn Mislav genug Zeit hat.
   407
   408	### Kurzbefehl-Idee für Status morgen
   409
   410	- IT15 ArgoCD App Status via WSL auf IT15.
   411	- DMZ Status via SSH `kube-bot@192.168.20.40` und `/etc/rancher/k3s/k3s.yaml`.
   412
   413
   414	## DMZ Infisical Bootstrap / kube-bot Machine Identity — 2026-06-16 18:33 UTC
   415
   416	- DMZ-Infisical ist temporär via Port-Forward erreichbar unter `http://192.168.20.40:18080`.
   417	- Mislav hat Organisation und Projekt in DMZ-Infisical angelegt.
   418	- DMZ-Infisical Projekt sichtbar für kube-bot:
   419	  - Name: `platform-kubernetes`
   420	  - ID: `d66f3d3b-1484-46f6-8142-f6fc32222b4d`
   421	  - Slug: `platform-kubernetes-pqmd`
   422	- Machine Identity in DMZ-Infisical:
   423	  - Name: `kube-bot`
   424	  - Client-ID: `9d47b9d2-c994-4449-afa1-5bbbf271eda0`
   425	- Client Secret wurde nicht in Slack/Markdown ausgegeben.
   426	- Recovery-/Bootstrap-Secrets liegen in IT15-Infisical:
   427	  - Projekt: `platform-kubernetes` (`c5e8661f-4b7a-43e1-80b0-8674f30950dc`)
   428	  - Environment: `prod`
   429	  - Pfad: `/platform/kube-bot`
   430	  - Secret-Namen: `DMZ_INFISICAL_KUBE_BOT_CLIENT_ID`, `DMZ_INFISICAL_KUBE_BOT_CLIENT_SECRET`, `DMZ_INFISICAL_URL`
   431	- Verification: kube-bot Universal Auth Login gegen DMZ-Infisical erfolgreich; `/api/v1/projects` zeigt `platform-kubernetes`.
   432	- Hinweis: Wunsch-Zielpfad `/platform/infisical/dmz/bootstrap` wurde noch nicht befüllt, weil die verfügbare API-Create-Route encrypted payload erwartet. Aktueller Pfad `/platform/kube-bot` ist funktional und verifiziert.
   433
   434	## Korrektur Tenant-Zuordnung — 2026-06-16 18:53 UTC
   435
   436	- Mislav hat klargestellt:  gehört fachlich zur **PIDOKA GmbH**, nicht zur Cattaro GmbH.
   437	- Für n8n-GitOps ist daher das Ziel-AppProject/der Zielpfad  zu verwenden bzw. entsprechend zu erweitern.
   438	- Bestehender Namespace ist aktuell ; fachliche Zielzuordnung: PIDOKA.
   439
   440	## Korrektur Tenant-Zuordnung — 2026-06-16 18:53 UTC
   441
   442	- Mislav hat klargestellt: n8n gehört fachlich zur **PIDOKA GmbH**, nicht zur Cattaro GmbH.
   443	- Für n8n-GitOps ist daher das Ziel-AppProject/der Zielpfad `tenant-pidoka` zu verwenden bzw. entsprechend zu erweitern.
   444	- Bestehender Namespace ist aktuell `hf-n8n`; fachliche Zielzuordnung: PIDOKA.
   445
   446	## PIDOKA n8n GitOps Vorbereitung — 2026-06-16 19:08 UTC
   447
   448	- Fachliche Korrektur: n8n gehört zur PIDOKA GmbH.
   449	- Bestehendes n8n läuft in DMZ Namespace `hf-n8n` und wird aktuell noch vom alten DMZ-ArgoCD `infra-argocd/n8n` verwaltet.
   450	- IT15-ArgoCD AppProject `tenant-pidoka` erlaubt bereits Zielnamespace `hf-n8n` und Source `8gears.container-registry.com`.
   451	- Neue GitOps-Manifeste wurden im Repo `GitMasterOne/platform-gitops` vorbereitet und gepusht:
   452	  - Commit: `8a58482 Add PIDOKA n8n GitOps migration manifest`
   453	  - `applications/tenants/pidoka/n8n.yaml`
   454	  - `tenants/pidoka/prod/n8n/values.yaml`
   455	  - `tenants/pidoka/prod/n8n/README.md`
   456	- Ziel der neuen App: IT15-ArgoCD Application `pidoka-n8n`, Project `tenant-pidoka`, Destination `https://192.168.20.40:6443`, Namespace `hf-n8n`.
   457	- SyncPolicy der neuen App bewusst vorsichtig: `prune=false`, `selfHeal=false`.
   458	- Kubernetes server-side dry-run auf IT15-ArgoCD war erfolgreich: `application.argoproj.io/pidoka-n8n created (server dry run)`.
   459	- Noch nicht erledigt: IT15-ArgoCD Application tatsächlich anlegen/syncen; alter DMZ-ArgoCD-Controller wurde nicht verändert.
   460	- Risiko: Zwei ArgoCD-Controller dürfen n8n nicht dauerhaft gleichzeitig verwalten. Cutover braucht explizites OK.
   461
   462	## PIDOKA n8n Cutover auf IT15-ArgoCD — 2026-06-16 19:28 UTC
   463
   464	- Freigabe durch Mislav: n8n direkt migrieren und danach ArgoCD UI bereitstellen.
   465	- Neue IT15-ArgoCD Application: `pidoka-n8n`, Project `tenant-pidoka`.
   466	- Ziel: DMZ `https://192.168.20.40:6443`, Namespace `hf-n8n`.
   467	- GitOps Repo Commit-Stand:
   468	  - `8a58482` initiale PIDOKA n8n Migration-Manifeste
   469	  - `814792f` IT15-App auf manual sync gesetzt
   470	  - `a10207a` Helm `releaseName: n8n`, damit bestehende Ressourcen übernommen statt neu erzeugt werden
   471	- IT15-ArgoCD Cluster Secret `dmz-k3s-tenant-cattaro-stage` wurde um Namespace `hf-n8n` erweitert.
   472	- DMZ RBAC namespace-scoped für ServiceAccount `platform-infisical/argocd-dmz-manager` in `hf-n8n` angelegt/erweitert.
   473	- Alter DMZ-ArgoCD Application-Controller für n8n wurde entkoppelt:
   474	  - `infra-argocd/n8n` Application gelöscht, vorher Backup auf DMZ Host: `/tmp/old-n8n-argocd-application-backup.yaml`
   475	  - n8n-Ressourcen wurden nicht gelöscht/pruned.
   476	- IT15-ArgoCD Status nach Cutover:
   477	  - `pidoka-n8n`: `Synced / Healthy`
   478	  - Ressourcen: ConfigMap/PVC/Service/ServiceAccount/Deployment/Ingress `n8n` in `hf-n8n` synced
   479	- DMZ Live-Status nach Cutover:
   480	  - Deployment `n8n`: `1/1`, Image `n8nio/n8n:1.122.4`
   481	  - PVC `n8n`: Bound, Longhorn 5Gi
   482	  - Ingress `n8n.heckenfels.com` unverändert
   483	- Hinweis: IT15-ArgoCD zeigt noch `SharedResourceWarning` mit alter App-ID `n8n`; funktional ist die App grün. Ursache sind alte ArgoCD tracking/instance Cache-/Tracking-Reste aus der Übernahme.
   484	- Temporärer IT15 ArgoCD UI Port-Forward läuft:
   485	  - IT15 WSL PID: `892996`
   486	  - URL aus Intranet voraussichtlich: `https://192.168.1.121:18081`
   487	  - Kein Ingress/Public Exposure.
   488
   489	## Legacy DMZ-ArgoCD n8n Quelle entfernt — 2026-06-16 19:59 UTC
   490
   491	- Mislav gab grünes Licht, die alte n8n-Quelle im Legacy-DMZ-ArgoCD zu entschärfen.
   492	- Im alten Repo `GitMasterOne/ArgoCD.git` wurde `applications/n8n.yaml` entfernt:
   493	  - Commit: `f8a3e69 Remove n8n from legacy DMZ ArgoCD app-of-apps`
   494	- Legacy Parent-App `infra-argocd/apps` wurde refreshed und ist danach `Synced / Healthy` auf Revision `f8a3e69`.
   495	- Legacy `infra-argocd/n8n` Application ist danach absent.
   496	- DMZ n8n Workloads blieben bestehen und healthy:
   497	  - Deployment `hf-n8n/n8n`: `1/1`
   498	  - PVC `hf-n8n/n8n`: Bound, Longhorn 5Gi
   499	  - Ingress `n8n.heckenfels.com` unverändert
   500	- IT15-ArgoCD `pidoka-n8n` bleibt `Synced / Healthy`.
   501	- IT15-ArgoCD listet nur noch eine n8n-App: `pidoka-n8n`.
   502	- Resthinweis: `pidoka-n8n` zeigt aktuell noch `SharedResourceWarning` mit alter App-ID `n8n`; keine zweite IT15-App existiert und Legacy-DMZ-App ist entfernt. Vermutlich stale resource-tracking/cache aus der Übernahme; funktional ist der Zustand grün.
   503
   504	## Recovery-Zwischenstand — PIDOKA HF Matomo Migration — 2026-06-17 11:04 UTC
   505
   506	Rekonstruiert aus lokalem Chat-/Sessionverlauf bis 2026-06-17 ca. 08:00 UTC. Dieser Abschnitt ist der aktuelle Wiedereinstiegspunkt nach Runtime-Abbruch.
   507
   508	### n8n Abschluss
   509
   510	- `n8n` gehört fachlich zur PIDOKA GmbH / HF-Servicegruppe.
   511	- IT15-ArgoCD verwaltet n8n produktiv:
   512	  - Application `pidoka-n8n`: zuletzt `Synced / Healthy`.
   513	  - Application `pidoka-n8n-secrets`: nach Normalisierung ebenfalls `Synced / Healthy`.
   514	- n8n Secret-Sync über ESO ist aktiv:
   515	  - `ExternalSecret/hf-n8n/n8n-secret` Ready / SecretSynced.
   516	  - `Deployment/hf-n8n/n8n` nutzt Secret-Refs für `N8N_BASIC_AUTH_USER`, `N8N_BASIC_AUTH_PASSWORD`, `N8N_ENCRYPTION_KEY`.
   517	- Letzte relevante GitOps-Commits:
   518	  - `559f471 Fix n8n chart extraEnv placement`
   519	  - `48b5515 Normalize n8n ExternalSecret defaults`
   520	- Keine Secretwerte wurden dokumentiert.
   521
   522	### Tenant-/Namespace-Zielmodell PIDOKA/HF
   523
   524	- Mislav hat bestätigt: `hf-*` Services sind zusammengehörige Services der PIDOKA GmbH.
   525	- Ziel-Namensschema: `pidoka-hf-*`, damit Tenant und HF-Servicegruppe sichtbar bleiben.
   526	- Geplante Zuordnung:
   527	  - `hf-n8n` -> `pidoka-hf-n8n` später / separat.
   528	  - `hf-matomo` -> `pidoka-hf-matomo` als erster Migrationskandidat.
   529	  - `hf-mautic` -> `pidoka-hf-mautic` später; vorher CronJob-Probleme prüfen.
   530	  - `hf-espocrm` -> `pidoka-hf-espocrm` später; vorher DB-CrashLoop prüfen.
   531	  - `hf-suitecrm` -> `pidoka-hf-suitecrm` später.
   532	  - `zammad` -> vermutlich `pidoka-hf-zammad`, aber ausdrücklich erst später, weil datenkritisch und lokaler Storage riskanter ist.
   533	- Mislav gab OK für app-by-app Migration, aber Bedingung: keine Datenverluste riskieren; Backup-/Rollback-Gate vor Cutover.
   534
   535	### Matomo Migration — bisher erledigt
   536
   537	- Startkandidat: `hf-matomo`, weil healthy, klein und Longhorn-basiert.
   538	- Vorgehen: Staging-Migration ohne Traffic-Cutover.
   539	- Backup-Gate bestanden:
   540	  - Backup-Pfad auf DMZ Control Plane: `/home/kube-bot/backups/matomo-20260617T060849Z`
   541	  - Live-Manifeste ohne Secretwerte gesichert: `/home/kube-bot/backups/matomo-live-manifests-20260617T061025Z.yaml`
   542	- Sensible Matomo DB-Werte lagen historisch als Literal-Env im alten Deployment. Sie wurden als Secret-Material behandelt und nicht ausgegeben.
   543	- Matomo-Secrets wurden nach DMZ-Infisical übertragen und verifiziert:
   544	  - Infisical-Pfad: `/tenants/pidoka/matomo`
   545	  - Secretwerte nicht dokumentiert.
   546	- GitOps-Staging-Manifeste wurden erstellt u
...(truncated)...

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '620,820p'"

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '620,820p'"

620	  - `MYSQL_USER: len=0`
   621	  - Passwortfelder waren ebenfalls nicht nutzbar/leer bzw. wurden nur maskiert betrachtet.
   622	- Alte Live-Deployment-Werte in `hf-matomo` sind vorhanden; nur Längen geprüft:
   623	  - `MATOMO_DATABASE_HOST` len 9
   624	  - DB/User-Namen len 6
   625	  - Passwörter vorhanden, nicht ausgegeben.
   626
   627	### Aktueller sicherer Zustand
   628
   629	- Neue `pidoka-hf-matomo` DB wurde wieder auf `replicas=0` skaliert.
   630	- Stuck Restore-Pod `matomo-html-restore` wurde gelöscht.
   631	- Neue Staging-Umgebung enthält keine produktive Traffic-Umschaltung.
   632	- Alte Produktion `hf-matomo` läuft weiter.
   633
   634	### Nächster Schritt
   635
   636	1. Alte Live-Matomo-Env-Werte maschinell aus `hf-matomo` lesen, nicht ausgeben.
   637	2. Werte nach DMZ-Infisical `/tenants/pidoka/matomo` upserten.
   638	3. ESO resyncen oder warten, dann nur Secret-Key-Längen in `pidoka-hf-matomo/matomo-secret` prüfen.
   639	4. Erst danach DB-Restore erneut starten.
   640	5. HTML-Restore muss auf Control-Plane `mbrkanov-mini-it13` laufen oder Backup muss auf Worker verfügbar sein; vorher Restore-Pod nodeSelector/affinity setzen oder Backup erreichbar machen.
   641
   642	## PIDOKA HF Matomo Staging-Restore — 2026-06-17 13:05 UTC
   643
   644	- Mislav gab OK, die Matomo-Secrets nach DMZ-Infisical zu upserten und den Restore fortzusetzen.
   645	- Secretwerte wurden nicht ausgegeben oder dokumentiert.
   646	- Live-Werte aus `hf-matomo` wurden maschinell gelesen und nach DMZ-Infisical übertragen:
   647	  - Projekt: `platform-kubernetes` (`d66f3d3b-1484-46f6-8142-f6fc32222b4d`)
   648	  - Environment: `prod`
   649	  - Pfad: `/tenants/pidoka/matomo`
   650	- GitOps-Korrektur gepusht:
   651	  - Repo: `GitMasterOne/platform-gitops`
   652	  - Commit: `815ea84 Fix Matomo ExternalSecret Infisical path`
   653	  - Ursache: ESO/Infisical braucht `secretsPath: /tenants/pidoka/matomo` im SecretStore und kurze `remoteRef.key`-Namen.
   654	- IT15 ArgoCD:
   655	  - `pidoka-hf-matomo`: `Synced / Healthy`, Revision `815ea84c63677765b7a3c986e0baa6f38581352d`
   656	  - `pidoka-hf-matomo-secrets`: `Synced / Healthy`, gleiche Revision
   657	- ESO-Verifikation im Namespace `pidoka-hf-matomo`:
   658	  - `SecretStore/dmz-infisical`: `Ready=True`, `Valid`
   659	  - `ExternalSecret/matomo-secret`: `Ready=True`, `SecretSynced`
   660	  - Alle erwarteten Secret-Keys haben nicht-leere Werte; nur Längen geprüft.
   661	- Staging-Restore durchgeführt:
   662	  - Staging-PVCs `matomo-pvc` und `matomo-db-pvc` geleert.
   663	  - HTML aus `/home/kube-bot/backups/matomo-20260617T060849Z/matomo-html.tar.gz` nach `matomo-pvc` wiederhergestellt.
   664	  - DB aus `/home/kube-bot/backups/matomo-20260617T060849Z/matomo-db.sql.gz` in frische MariaDB auf `matomo-db-pvc` importiert.
   665	  - DB-Verifikation: 53 Tabellen, 2 Einträge in `matomo_site`.
   666	  - HTML-Verifikation: `index.php` und `config/` vorhanden, 30 Top-Level-Einträge.
   667	- Interner App-Test:
   668	  - `Deployment/matomo` temporär auf 1 skaliert.
   669	  - Interner HTTP-Test im Pod: `200`.
   670	  - Keine Restarts.
   671	  - Danach `matomo` und `matomo-db` wieder auf `replicas=0` skaliert.
   672	- Produktion blieb unverändert:
   673	  - Namespace `hf-matomo`
   674	  - Deployments `matomo` und `matomo-db`: `1/1`
   675	  - Pods Running, Restarts `0`
   676	  - Ingress `matomo.heckenfels.com` unverändert.
   677	- Wichtiger Hinweis:
   678	  - Staging zog ein anderes `matomo:latest` Image-Digest als die laufende Produktion. Vor Cutover sollte das Image auf eine feste Version/Digest gepinnt oder bewusst abgeglichen werden.
   679	  - Es gab keinen Traffic-Cutover und kein neues Ingress.
   680	- Lokaler GitOps-Worktree-Hinweis:
   681	  - Es existiert weiterhin eine uncommitted Änderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; diese wurde nicht angefasst und nicht gepusht.
   682
   683	### Nächster empfohlener Schritt
   684
   685	1. Matomo-Staging-Image pinnen/angleichen, vorzugsweise auf die produktiv verifizierte Version statt `latest`.
   686	2. Danach Staging-App erneut intern testen.
   687	3. Erst danach Cutover planen: DNS/Ingress/Namespace-Wechsel oder sauberer Ersatz der alten `hf-matomo` Ressourcen.
   688	4. Vor Cutover erneut Backup/Restore-Punkt prüfen und Rollback-Pfad festlegen.
   689
   690	## PIDOKA HF Matomo Image-Pin + Retest — 2026-06-17 13:35 UTC
   691
   692	- Staging-Images wurden auf die aktuell produktiv laufenden Image-Digests gepinnt:
   693	  - Matomo: `docker.io/library/matomo@sha256:21b8bae018cd51a05f36bc6beac3861bb314d131df690c47bba1648aad2b8d7e`
   694	  - MariaDB: `docker.io/library/mariadb@sha256:e0236fc6386e7eacd9359e59d0a078bd7aa0d18280d36d13061121bedeaee903`
   695	- GitOps Commit:
   696	  - Repo: `GitMasterOne/platform-gitops`
   697	  - Commit: `9a8b373 Pin Matomo staging images to production digests`
   698	- IT15 ArgoCD:
   699	  - `pidoka-hf-matomo`: `Synced / Healthy`, Revision `9a8b373abdf4f0bb1e5d3959c2ceaee50b87584f`
   700	  - `pidoka-hf-matomo-secrets`: `Synced / Healthy`, gleiche Revision
   701	- Interner Staging-Retest:
   702	  - `matomo-db` und `matomo` temporär auf `replicas=1` skaliert.
   703	  - Beide Pods liefen mit den gepinnten produktiven Digests.
   704	  - Restarts: `0`.
   705	  - Interner HTTP-Test im Matomo-Pod: `200`.
   706	  - DB-Check: 53 Tabellen, 2 Einträge in `matomo_site`.
   707	  - Danach Staging wieder auf `replicas=0` skaliert.
   708	- Produktion `hf-matomo` blieb unverändert:
   709	  - `matomo` und `matomo-db`: `1/1`
   710	  - Pods Running, Restarts `0`
   711	  - Ingress `matomo.heckenfels.com` unverändert.
   712	- Lokaler GitOps-Worktree-Hinweis:
   713	  - Weiterhin uncommitted: `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht Teil der Matomo-Arbeit.
   714
   715	## PIDOKA HF Zammad Analyse + DB-Backup — 2026-06-17 19:40 UTC
   716
   717	- Mislav gab ein kleines Wartungsfenster frei: vorsichtig, kleine Schritte, laufend berichten.
   718	- Zammad wurde vorab read-only analysiert:
   719	  - Namespace: `zammad`.
   720	  - Helm Release: `zammad`, Chart `zammad-10.2.1`, App `6.2.0-1`, Revision `1`.
   721	  - Keine ArgoCD Application fuer Zammad sichtbar; aktuell Helm-managed.
   722	  - Service: `LoadBalancer` Port `8080`, NPM/Externpfad `service.heckenfels.com`.
   723	  - Storage: vier `local-path` PVCs auf `mbrkanov-mini-it13`, ReclaimPolicy `Delete`.
   724	- Backup-Pfad auf DMZ Control Plane:
   725	  - `/home/kube-bot/backups/zammad-20260617T193554Z`
   726	- Gesichert:
   727	  - `status-before.txt`
   728	  - `status-after.txt`
   729	  - `helm-status.txt`
   730	  - `zammad-manifests-no-secrets.yaml`
   731	  - `README.txt`
   732	  - `zammad-postgresql.sql.gz`
   733	  - `SHA256SUMS`
   734	- Secretwerte wurden nicht ausgegeben oder exportiert.
   735	- Fuer konsistenten DB-Dump wurde nur `StatefulSet/zammad` temporaer auf `replicas=0` skaliert.
   736	- PostgreSQL, Redis, Elasticsearch blieben online.
   737	- DB-Dump:
   738	  - Datei: `/home/kube-bot/backups/zammad-20260617T193554Z/zammad-postgresql.sql.gz`
   739	  - Groesse: ca. `191M`
   740	  - SHA256: `75af32c1d0fe94f89af541cdc89300464cb648391c5aff56b77a780082927210`
   741	  - `gzip -t` erfolgreich.
   742	  - `sha256sum -c` erfolgreich.
   743	- Zammad wurde danach wieder auf `replicas=1` skaliert.
   744	- Abschlusszustand:
   745	  - `zammad-0`: `4/4 Running`, neuer Pod ohne Restarts.
   746	  - `https://service.heckenfels.com/`: HTTP `200`.
   747	- Naechste sichere Schritte:
   748	  - Optional: Zammad-Datei-/PVC-Backup fuer `zammad-var`, Redis und Elasticsearch ergaenzen.
   749	  - Danach GitOps-Zielmodell entscheiden: bestehendes `zammad` adoptieren oder spaeter nach `pidoka-hf-zammad` migrieren.
   750	  - Keine Migration/Cleanup ohne separates OK.
   751
   752	### Ergaenzung — Zammad PVC-Dateisicherung — 2026-06-17 19:55 UTC
   753
   754	- Nach Mislavs OK wurden zusaetzlich die vier `local-path` PV-Verzeichnisse gesichert.
   755	- Fuer die Dateisicherung wurde erneut nur `StatefulSet/zammad` temporaer auf `replicas=0` skaliert.
   756	- PostgreSQL, Redis, Elasticsearch blieben online.
   757	- Backup-Dateien im selben Pfad:
   758	  - `/home/kube-bot/backups/zammad-20260617T193554Z/pvc-zammad-postgresql.tar.gz` ca. `239M`
   759	  - `/home/kube-bot/backups/zammad-20260617T193554Z/pvc-zammad-redis.tar.gz` ca. `7.2M`
   760	  - `/home/kube-bot/backups/zammad-20260617T193554Z/pvc-zammad-elasticsearch.tar.gz` ca. `4.5M`
   761	  - `/home/kube-bot/backups/zammad-20260617T193554Z/pvc-zammad-var.tar.gz` ca. `6.9K`
   762	  - `/home/kube-bot/backups/zammad-20260617T193554Z/status-after-pvc-backup.txt`
   763	- `SHA256SUMS` wurde um DB-Dump und PVC-Tarballs erweitert.
   764	- `sha256sum -c SHA256SUMS` erfolgreich fuer alle fuenf Artefakte.
   765	- `gzip -t` erfolgreich fuer alle vier PVC-Tarballs.
   766	- Backup-Ordner gesamt: ca. `441M`.
   767	- Abschlusszustand:
   768	  - `zammad-0`: `4/4 Running`, neuer Pod ohne Restarts.
   769	  - `https://service.heckenfels.com/`: HTTP `200`.
   770	- Hinweis: Die PVC-Tarballs sind Dateisicherungen der laufenden Backend-PVs; der PostgreSQL-Dump bleibt das primaere konsistente DB-Artefakt.
   771
   772	### Ergaenzung — Zammad GitOps-Adoptionsvorbereitung — 2026-06-17 20:10 UTC
   773
   774	- Nach Mislavs OK wurde sorgfaeltig nur lokal/read-only weitergearbeitet.
   775	- Live-Helm-Release wurde sanitizt exportiert:
   776	  - `/home/kube-bot/backups/zammad-20260617T193554Z/helm-metadata.txt`
   777	  - `/home/kube-bot/backups/zammad-20260617T193554Z/helm-values-all-redacted.json`
   778	  - `/home/kube-bot/backups/zammad-20260617T193554Z/helm-manifest-no-secrets.yaml`
   779	- `helm-values-all-redacted.json` enthaelt keine absichtlich ausgegebenen Secretwerte; sensitive Keys wurden ersetzt.
   780	- `helm-manifest-no-secrets.yaml` enthaelt keine Kubernetes `Secret`-Dokumente.
   781	- Chart-Metadaten:
   782	  - Helm Release `zammad`
   783	  - Chart `zammad-10.2.1`
   784	  - App `6.2.0-1`
   785	  - Dependencies: Elasticsearch, Memcached, PostgreSQL, Redis
   786	- Helm-Chart-Quelle:
   787	  - Aktuelle Zammad-Helm-Seite/Repo verweist auf `https://github.com/zammad/zammad-helm`.
   788	  - Der direkte GitHub Release Asset fuer `zammad-10.2.1.tgz` existiert noch.
   789	  - Der aktuelle Helm-Index listet `10.2.1` aber nicht mehr per `helm pull`; daher wurde fuer die erste Adoptionsvorlage eine statisch gerenderte, sanitizte Manifest-Variante gewaehlt.
   790	- Lokale GitOps-Vorlage erstellt, nicht gepusht und nicht angewendet:
   791	  - `repos/platform-gitops/applications/tenants/pidoka/zammad.yaml`
   792	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/app.yaml`
   793	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/kustomization.yaml`
   794	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/README.md`
   795	- Ziel:
   796	  - ArgoCD Application `pidoka-hf-zammad`
   797	  - Project `tenant-pidoka`
   798	  - Destination Namespace `zammad`
   799	  - Kein automatischer Sync, kein Prune.
   800	- Validierung:
   801	  - Kustomize rendert 19 Ressourcen im Namespace `zammad`.
   802	  - Keine `Secret`-Ressourcen im Render.
   803	  - DMZ `kubectl apply --dry-run=server` erfolgreich.
   804	  - Dry-run meldet erwartbare Adoption-Warnungen: bestehende Ressourcen haben keine `kubectl.kubernetes.io/last-applied-configuration` Annotation, weil sie historisch Helm-managed sind.
   805	  - Externer Check danach: `https://service.heckenfels.com/` HTTP `200`.
   806	- Wichtiger GitOps-Worktree-Hinweis:
   807	  - Es existiert weiterhin eine aeltere uncommitted n8n-Aenderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; sie wurde nicht angefasst.
   808	- Naechster sicherer Schritt:
   809	  - Secret-Key-Inventar fuer Zammad erfassen und Infisical/ESO-Zielmodell vorbereiten, ohne Werte auszugeben.
   810
...(truncated)...

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '820,1040p'"

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '820,1040p'"

820	  - `zammad-postgresql-pass` (`Opaque`): `postgresql-pass` len 6
   821	  - `zammad-redis` (`Opaque`): `redis-password` len 6
   822	  - `zammad-redis-pass` (`Opaque`): `redis-password` len 6
   823	- Keine Secretwerte wurden ausgegeben.
   824	- Lokale GitOps/ESO-Vorlage erstellt, nicht gepusht und nicht angewendet:
   825	  - `repos/platform-gitops/applications/tenants/pidoka/zammad-secrets.yaml`
   826	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/external-secrets/kustomization.yaml`
   827	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/external-secrets/zammad-secrets.yaml`
   828	- Zielmodell:
   829	  - Infisical Pfad `platform-kubernetes/prod:/tenants/pidoka/zammad`
   830	  - SecretStore `zammad/dmz-infisical`
   831	  - ExternalSecrets erhalten die bestehenden Ziel-Secret-Namen.
   832	  - Remote-Key-Namen:
   833	    - `POSTGRESQL_PASSWORD`
   834	    - `POSTGRESQL_POSTGRES_PASSWORD`
   835	    - `ZAMMAD_POSTGRESQL_PASS`
   836	    - `REDIS_PASSWORD`
   837	    - `ZAMMAD_REDIS_PASS`
   838	- Validierung:
   839	  - Kustomize/DMZ server-side dry-run erfolgreich.
   840	  - Render enthaelt vier `ExternalSecret` und einen `SecretStore`.
   841	  - Render enthaelt keine Kubernetes `Secret`-Ressourcen.
   842	- Offener Blocker vor echtem ESO-Sync:
   843	  - `zammad/infisical-universal-auth` fehlt aktuell.
   844	  - Dieses Auth-Secret muesste vor Sync aus einem funktionierenden PIDOKA-ESO-Namespace kopiert oder sauber bereitgestellt werden.
   845	  - Das ist eine Secret-/Cluster-Aenderung und braucht separates OK.
   846	- Wichtiger GitOps-Worktree-Hinweis:
   847	  - Weiterhin vorhanden: aeltere uncommitted n8n-Aenderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht angefasst.
   848
   849	### Ergaenzung — Zammad Secrets nach Infisical + ESO live — 2026-06-17 20:35 UTC
   850
   851	- Mislav gab OK fuer den schreibenden Secret-/ESO-Schritt.
   852	- Zammad-Secretwerte wurden maschinell aus bestehenden Kubernetes Secrets gelesen und nach DMZ-Infisical geschrieben.
   853	- Keine Secretwerte wurden ausgegeben.
   854	- Infisical:
   855	  - Projekt: `platform-kubernetes` (`d66f3d3b-1484-46f6-8142-f6fc32222b4d`)
   856	  - Environment: `prod`
   857	  - Pfad: `/tenants/pidoka/zammad`
   858	  - Ordner `/tenants/pidoka/zammad` wurde angelegt.
   859	  - Keys geschrieben:
   860	    - `POSTGRESQL_PASSWORD`
   861	    - `POSTGRESQL_POSTGRES_PASSWORD`
   862	    - `ZAMMAD_POSTGRESQL_PASS`
   863	    - `REDIS_PASSWORD`
   864	    - `ZAMMAD_REDIS_PASS`
   865	- `infisical-universal-auth` wurde aus einem funktionierenden PIDOKA-ESO-Namespace nach `zammad` kopiert.
   866	- ESO-Ressourcen wurden live angelegt:
   867	  - `SecretStore/zammad/dmz-infisical`
   868	  - `ExternalSecret/zammad/zammad-postgresql`
   869	  - `ExternalSecret/zammad/zammad-postgresql-pass`
   870	  - `ExternalSecret/zammad/zammad-redis`
   871	  - `ExternalSecret/zammad/zammad-redis-pass`
   872	- Wegen bestehender Kubernetes Secrets nutzt die Zammad-ESO-Vorlage `creationPolicy: Merge` und `deletionPolicy: Retain`.
   873	- Verifikation:
   874	  - `SecretStore/zammad/dmz-infisical`: `Ready=True`, `Valid`, `ReadOnly`
   875	  - Alle vier ExternalSecrets: `SecretSynced`, `Ready=True`
   876	  - Ziel-Secret-Key-Laengen unveraendert gegen Vorinventar:
   877	    - `zammad-postgresql/password` len 6
   878	    - `zammad-postgresql/postgres-password` len 6
   879	    - `zammad-postgresql-pass/postgresql-pass` len 6
   880	    - `zammad-redis/redis-password` len 6
   881	    - `zammad-redis-pass/redis-password` len 6
   882	  - Zammad Pods: Running, `zammad-0` `4/4`, Restarts `0`
   883	  - `https://service.heckenfels.com/`: HTTP `200`
   884	- Statusartefakte:
   885	  - `/home/kube-bot/backups/zammad-20260617T193554Z/status-eso-after.txt`
   886	  - `/home/kube-bot/backups/zammad-20260617T193554Z/secretstore-dmz-infisical.yaml`
   887	  - `/home/kube-bot/backups/zammad-20260617T193554Z/externalsecrets-zammad.yaml`
   888	- Wichtiger GitOps-Worktree-Hinweis:
   889	  - Die Zammad GitOps-/ESO-Dateien sind lokal vorbereitet, aber noch nicht gepusht.
   890	  - Live-ESO wurde manuell angewendet und sollte zeitnah durch GitOps nachgezogen werden.
   891	  - Weiterhin vorhanden: aeltere uncommitted n8n-Aenderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht angefasst.
   892
   893	### Ergaenzung — Zammad GitOps gepusht — 2026-06-17 20:45 UTC
   894
   895	- Mislav gab OK, den GitOps-Stand nachzuziehen.
   896	- Lokaler Commit erstellt und nach `origin/main` gepusht:
   897	  - Commit: `4797ae3 Add PIDOKA Zammad GitOps adoption`
   898	- Enthalten:
   899	  - `applications/tenants/pidoka/zammad.yaml`
   900	  - `applications/tenants/pidoka/zammad-secrets.yaml`
   901	  - `tenants/pidoka/prod/zammad/app.yaml`
   902	  - `tenants/pidoka/prod/zammad/kustomization.yaml`
   903	  - `tenants/pidoka/prod/zammad/README.md`
   904	  - `tenants/pidoka/prod/zammad/external-secrets/kustomization.yaml`
   905	  - `tenants/pidoka/prod/zammad/external-secrets/zammad-secrets.yaml`
   906	- Push brachte auch die bereits lokalen Mautic-Commits hoch:
   907	  - `624f944 Add clean PIDOKA Mautic deployment`
   908	  - `fd8a65b Use MariaDB LTS for Mautic`
   909	- Kein ArgoCD-Sync/Apply durch diesen Schritt.
   910	- Verifikation nach Push:
   911	  - Git `main...origin/main` sauber, bis auf die bekannte lokale n8n-Dateiaenderung.
   912	  - Zammad Pods Running, `zammad-0` `4/4`, Restarts `0`.
   913	  - Zammad ExternalSecrets alle `SecretSynced=True`.
   914	  - `https://service.heckenfels.com/`: HTTP `200`.
   915	- Weiterhin offen:
   916	  - Aeltere uncommitted n8n-Aenderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht angefasst.
   917	  - Zammad ArgoCD Applications sind im Repo vorhanden, aber nicht automatisch angelegt/synchronisiert, sofern keine Parent-App diesen Pfad managed.
   918	  - Naechster Schritt waere ArgoCD-Diff/Adoption nur mit separatem OK.
   919
   920	## PIDOKA HF Mautic Cleanup + Clean Install — 2026-06-17 16:40 UTC
   921
   922	- Mislav gab explizites OK: alte Legacy-Mautic-App und zugehörige PVCs dürfen gelöscht werden; danach sauber neu aufsetzen.
   923	- Vor Cleanup verifiziert:
   924	  - Alte DB war nicht leer, aber inkonsistent: ca. 107 Tabellen mit Prefix `mtc_`; alte CronJobs suchten Tabellen ohne Prefix.
   925	  - Live-Konfig hatte `db_table_prefix => null`; alte Chart-Env nutzte u.a. `MAUTIC_DB_NAME`, während Mautic `MAUTIC_DB_DATABASE` erwartet.
   926	  - Alte CronJobs liefen in `CrashLoopBackOff` wegen `Table 'mautic.campaigns' doesn't exist`.
   927	- Legacy-DMZ-ArgoCD entschärft:
   928	  - Altes Repo `GitMasterOne/ArgoCD.git`: `applications/hf-mautic.yaml` entfernt.
   929	  - Commit: `664e83e Remove Mautic from legacy DMZ ArgoCD app-of-apps`.
   930	  - Legacy Parent-App `infra-argocd/apps`: danach `Synced / Healthy`, Revision `664e83e`.
   931	  - Alte `infra-argocd/hf-mautic` Application gelöscht.
   932	- Alte DMZ-Ressourcen entfernt:
   933	  - Namespace `hf-mautic` inklusive alter Workloads, CronJobs, Secret, ConfigMaps und PVCs gelöscht.
   934	  - Alte PVs/PVCs `data-hf-mautic-mariadb-0` und `redis-data-hf-mautic-redis-master-0` sind nicht mehr im Cluster sichtbar.
   935	- Neue DMZ-Infisical-Secrets angelegt:
   936	  - Projekt: `platform-kubernetes` (`d66f3d3b-1484-46f6-8142-f6fc32222b4d`)
   937	  - Environment: `prod`
   938	  - Pfad: `/tenants/pidoka/mautic`
   939	  - Secretwerte wurden nicht ausgegeben oder dokumentiert.
   940	  - Erwartete Keys wurden via ESO in `hf-mautic/mautic-secret` synchronisiert; nur Längen geprüft.
   941	- Neues GitOps-Setup:
   942	  - Repo `GitMasterOne/platform-gitops`
   943	  - Commit `624f944 Add clean PIDOKA Mautic deployment`
   944	  - Commit `fd8a65b Use MariaDB LTS for Mautic`
   945	  - Neue IT15-ArgoCD Apps:
   946	    - `pidoka-hf-mautic-secrets`
   947	    - `pidoka-hf-mautic`
   948	  - Beide Apps zuletzt `Synced / Healthy`, Revision `fd8a65be5d4abfd4ac7eec255de2bea2136a8f6a`.
   949	- Neuer Live-Zustand in DMZ `hf-mautic`:
   950	  - `mautic-db-0`: `1/1 Running`, MariaDB `10.11`, PVC `mautic-db-pvc` 10Gi Longhorn.
   951	  - `mautic`: `1/1 Running`, Image `mautic/mautic:5-apache`, PVC `mautic-data-pvc` 5Gi Longhorn.
   952	  - `mautic-cron`: `1/1 Running`, Image `mautic/mautic:5-apache`.
   953	  - Ingress `mautic.heckenfels.com` über Traefik vorhanden.
   954	  - Interner HTTP-Test: `/` leitet auf `/index.php/installer`; Installer antwortet HTTP 200.
   955	  - DB ist frisch und leer: 0 Tabellen, Mautic noch nicht durch Installer eingerichtet.
   956	- Während Aufbau behoben:
   957	  - `mariadb:11.8` hing bei `mariadb-install-db`; auf `mariadb:10.11` geändert.
   958	  - `MAUTIC_TRUSTED_PROXIES` musste JSON sein; Wert in Infisical auf JSON-Array korrigiert.
   959	  - Docker-Hub-DNS/Pull war temporär langsam, später erfolgreich.
   960	- Offener nächster Schritt:
   961	  - Mautic Installer unter `https://mautic.heckenfels.com` abschließen oder CLI-Installationsweg definieren.
   962	  - Danach DB-Tabellen/Health/Cron-Funktion prüfen.
   963	- Lokaler GitOps-Worktree-Hinweis:
   964	  - Es existiert weiterhin eine uncommitted Änderung an `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; diese wurde nicht angefasst und nicht gepusht.
   965
   966	### Nächster empfohlener Schritt
   967
   968	Cutover-Plan für Matomo ausarbeiten, bevor Traffic umgestellt wird:
   969	1. finalen Pre-Cutover-Backupzeitpunkt definieren,
   970	2. Freeze-/Wartungsfenster klären,
   971	3. Ingress/Traffic-Umschaltung auswählen,
   972	4. Rollback-Pfad festlegen,
   973	5. danach erst mit explizitem OK umstellen.
   974
   975	## PIDOKA HF Matomo Cutover — 2026-06-17 14:30 UTC
   976
   977	- Mislav meldete ein Wartungsfenster: aktuell arbeitet niemand mit Matomo.
   978	- Cutover wurde durchgeführt.
   979	- Secretwerte wurden nicht ausgegeben.
   980
   981	### Freeze und finaler Stand
   982
   983	- Alte Produktion `hf-matomo/matomo` wurde auf `replicas=0` skaliert, um Writes während Backup/Restore zu stoppen.
   984	- Alte DB `hf-matomo/matomo-db` blieb `1/1` für Dump und Rollback.
   985	- Finaler DB-Dump:
   986	  - `/home/kube-bot/backups/matomo-cutover-20260617T135148Z/matomo-db.sql.gz`
   987	  - SHA256 geprüft.
   988	- Altes Ingress für Rollback gesichert:
   989	  - `/home/kube-bot/backups/matomo-cutover-20260617T135148Z/old-matomo-ingress.yaml`
   990	  - SHA256 geprüft.
   991	- Finales HTML-Backup wurde versucht, aber der Tar-Prozess lief zu lange und wurde abgebrochen.
   992	  - Incomplete Datei: `/home/kube-bot/backups/matomo-cutover-20260617T135148Z/matomo-html.tar.gz.incomplete`
   993	  - Nicht für Restore verwenden.
   994	  - Neuer Matomo-HTML-PVC nutzt weiterhin den vorher verifizierten Restore aus `/home/kube-bot/backups/matomo-20260617T060849Z/matomo-html.tar.gz`.
   995
   996	### Finaler Restore in neues Ziel
   997
   998	- Namespace: `pidoka-hf-matomo`
   999	- DB-PVC `matomo-db-pvc` wurde geleert und mit finalem DB-Dump neu importiert.
  1000	- DB-Verifikation nach finalem Import:
  1001	  - 53 Tabellen
  1002	  - 2 Einträge in `matomo_site`
  1003	- App/DB laufen mit gepinnten Produktions-Digests:
  1004	  - Matomo: `docker.io/library/matomo@sha256:21b8bae018cd51a05f36bc6beac3861bb314d131df690c47bba1648aad2b8d7e`
  1005	  - MariaDB: `docker.io/library/mariadb@sha256:e0236fc6386e7eacd9359e59d0a078bd7aa0d18280d36d13061121bedeaee903`
  1006
  1007	### GitOps / ArgoCD
  1008
  1009	- GitOps Commits:
  1010	  - `5851072 Add Matomo cutover ingress`
  1011	  - `d625118 Enable Matomo cutover workloads`
  1012	- IT15 ArgoCD:
  1013	  - `pidoka-hf-matomo`: `Synced / Healthy`, Revision `d6251183310cc6e3446fb2bb77d91450ddfb66e4`
  1014	  - `pidoka-hf-matomo-secrets`: zuletzt `Synced / Healthy`
  1015	- Neuer Ingress:
  1016	  - Namespace `pidoka-hf-matomo`
  1017	  - Name `matomo-ingress`
  1018	  - Host `matomo.h
...(truncated)...

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '1040,1240p'"

/bin/bash -lc "nl -ba SESSION_HANDOFF.md | sed -n '1040,1240p'"

1040
  1041	Wenn Rollback nötig:
  1042	1. Neues Ingress `pidoka-hf-matomo/matomo-ingress` löschen oder GitOps-App auf vorherigen Stand zurücksyncen.
  1043	2. Altes Ingress aus `/home/kube-bot/backups/matomo-cutover-20260617T135148Z/old-matomo-ingress.yaml` wieder anwenden.
  1044	3. Alte App `hf-matomo/matomo` wieder auf `replicas=1` skalieren.
  1045	4. Prüfen: `https://matomo.heckenfels.com/` HTTP `200`.
  1046
  1047	### Offene Nacharbeiten
  1048
  1049	- Alte `hf-matomo` Ressourcen nicht sofort löschen; mindestens kurze Beobachtungsphase abwarten.
  1050	- Wenn Matomo stabil bleibt: Altbestand geplant entfernen oder archivieren, nur mit explizitem OK.
  1051	- Incomplete HTML-Backup-Datei kann später entfernt werden, wenn kein Bedarf besteht.
  1052	- Lokaler GitOps-Worktree-Hinweis:
  1053	  - Weiterhin uncommitted: `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht Teil der Matomo-Arbeit.
  1054
  1055	## Zammad GitOps-Adoption vorbereitet — 2026-06-17 22:03 UTC
  1056
  1057	- Fokus nach Mislavs OK: Zammad-Adoption risikoarm vorbereiten, ohne Live-Sync.
  1058	- Live-Zustand vor/nach Prüfung:
  1059	  - `https://service.heckenfels.com/`: HTTP `200`.
  1060	  - `zammad-0`: `4/4 Running`, Container-Restarts `0`.
  1061	  - PostgreSQL, Redis, Elasticsearch, Memcached: Running.
  1062	  - Zammad ESO: alle vier ExternalSecrets `SecretSynced=True`, SecretStore `Ready=True`.
  1063	- Befund:
  1064	  - `pidoka-hf-zammad-secrets` hatte server-side diff ohne Ausgabe / Exit 0.
  1065	  - `pidoka-hf-zammad` hatte Apply-Konflikte auf Helm-owned StatefulSet `volumeClaimTemplates`.
  1066	- Lokale GitOps-Korrektur vorbereitet, noch nicht gepusht und nicht gesynct:
  1067	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/app.yaml`
  1068	    - `volumeClaimTemplates` aus den bestehenden Helm-StatefulSets entfernt.
  1069	    - `apiVersion: v1` am Elasticsearch `MY_POD_NAME` fieldRef ergänzt.
  1070	  - `repos/platform-gitops/tenants/pidoka/prod/zammad/README.md`
  1071	    - Hinweis ergänzt, dass StatefulSet-PVC-Templates bei der Adoption absichtlich live/Helm-owned bleiben.
  1072	- Verifikation:
  1073	  - `npx kustomize build tenants/pidoka/prod/zammad` erfolgreich.
  1074	  - DMZ `kubectl diff --server-side=true -f -` gegen gerenderten Zammad-Stand: keine Ausgabe / Exit 0.
  1075	  - Zammad danach weiterhin HTTP `200`, Pods Running.
  1076	- Weiterhin lokal uncommitted und nicht Teil dieser Arbeit:
  1077	  - `repos/platform-gitops/tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`.
  1078	- Nächster Schritt mit explizitem OK:
  1079	  - Zammad-Adoptionsfix committen/pushen.
  1080	  - Danach ArgoCD refresh/diff prüfen.
  1081	  - Erst danach optional `pidoka-hf-zammad-secrets` und `pidoka-hf-zammad` syncen, ohne Prune.
  1082
  1083	## Zammad GitOps-Adoptionsfix gepusht — 2026-06-17 22:07 UTC
  1084
  1085	- Mislav gab OK zum Commit/Push.
  1086	- Commit im Repo `GitMasterOne/platform-gitops`:
  1087	  - `edc5624 Prepare Zammad GitOps adoption diff`
  1088	- Enthalten:
  1089	  - `tenants/pidoka/prod/zammad/app.yaml`
  1090	  - `tenants/pidoka/prod/zammad/README.md`
  1091	- Push nach `origin/main` erfolgreich.
  1092	- IT15 ArgoCD Refresh wurde nur auf den beiden Zammad Applications angestoßen, kein Sync:
  1093	  - `pidoka-hf-zammad`: danach `Synced / Healthy`, Revision `edc56244b52263300752a3489134c6d4e3d8e024`.
  1094	  - `pidoka-hf-zammad-secrets`: weiterhin `OutOfSync / Healthy`, Revision `edc56244b52263300752a3489134c6d4e3d8e024`.
  1095	- Verifikation:
  1096	  - DMZ server-side diff für `tenants/pidoka/prod/zammad`: keine Ausgabe / Exit 0.
  1097	  - DMZ server-side diff für `tenants/pidoka/prod/zammad/external-secrets`: keine Ausgabe / Exit 0.
  1098	  - Zammad `https://service.heckenfels.com/`: HTTP `200`.
  1099	  - Zammad ExternalSecrets weiterhin `SecretSynced=True`.
  1100	- Einschätzung:
  1101	  - Haupt-Zammad-App ist erfolgreich als ArgoCD-Adoptionsstand sauber.
  1102	  - Secrets-App ist funktional gesund, aber ArgoCD zeigt OutOfSync vermutlich wegen noch fehlender ArgoCD-Übernahme/Tracking der bereits manuell angewendeten ESO-Objekte.
  1103	- Nächster Schritt mit explizitem OK:
  1104	  - `pidoka-hf-zammad-secrets` einmal ohne Prune syncen, um ArgoCD-Tracking nachzuziehen.
  1105	  - Danach Status prüfen; falls grün, keine weitere Aktion nötig.
  1106
  1107	## Zammad Secrets-App synchronisiert — 2026-06-17 22:10 UTC
  1108
  1109	- Mislav gab OK zum Sync.
  1110	- Durchgeführt:
  1111	  - Nur `pidoka-hf-zammad-secrets` synchronisiert.
  1112	  - `prune=false`.
  1113	  - `ServerSideApply=true`.
  1114	  - Kein Sync der Haupt-Zammad-App nötig, da diese bereits `Synced / Healthy` war.
  1115	- Ergebnis IT15 ArgoCD:
  1116	  - `pidoka-hf-zammad`: `Synced / Healthy`.
  1117	  - `pidoka-hf-zammad-secrets`: `Synced / Healthy`, Operation `Succeeded`.
  1118	- Ergebnis DMZ:
  1119	  - `https://service.heckenfels.com/`: HTTP `200`.
  1120	  - Zammad Pods Running:
  1121	    - `zammad-0`: `4/4`, Container-Restarts `0`.
  1122	    - PostgreSQL, Redis, Elasticsearch, Memcached Running.
  1123	  - ESO:
  1124	    - `SecretStore/zammad/dmz-infisical`: `Valid`, `Ready=True`.
  1125	    - `ExternalSecret` `zammad-postgresql`, `zammad-postgresql-pass`, `zammad-redis`, `zammad-redis-pass`: `SecretSynced=True`.
  1126	- Lokaler GitOps-Stand:
  1127	  - `main...origin/main` sauber.
  1128	  - Weiterhin uncommitted: `tenants/pidoka/prod/n8n/external-secrets/n8n-secret.yaml`; nicht Teil der Zammad-Arbeit.
  1129	- Schlussfolgerung:
  1130	  - Zammad ist jetzt in IT15-ArgoCD adoptiert und die Secret-/ESO-Schicht ist GitOps-synchronisiert.
  1131	  - Kein Prune/Cleanup durchgeführt.