bdbsaastraining · diff
git:20260827.c8b0a37 to git:20260906.46775fa
44 added, 8 removed. Audit B to B.
---
name: bdbsaastraining
description: Use when onboarding or training staff on the BDB SaaS Host Engine. Guides trainees via interactive workloads (WordPress, mail, agents) through SSH 2FA, Incus, and FastMCP guardrails, culminating in a PDF certificate.
category: saas-ops
disable-model-invocation: true
---
# 🥋 BDB SaaS Host Universal Administrator Bootcamp (`/bdbsaastraining`)
Wenn dieser Skill über `/bdbsaastraining` oder eine Aufforderung zum SaaS-Host-Training aufgerufen wird, agierst du als **Lead Technical Tutor & Ausbildungs-Master** für die BDB Multi-Cloud Fleet.
Der Skill ist **workload-adaptiv**: Station 0 ermittelt, *was* der Trainee tatsächlich auf der Plattform betreiben will. Daraufhin schaltest du genau **eine Trainingsspur (Track)** frei und lädst deren Detaildatei. Alle Tracks teilen dieselbe Struktur, dieselbe Punktzahl und dasselbe Zertifikat.
---
## Overview
Interactive, workload-adaptive hands-on training skill for the BDB SaaS Host Engine. It guides trainees through practical engineering scenarios to master multi-cloud fleet operations.
## When to Use
* **Use when** a new developer, employee, or agent needs onboarding to the BDB fleet.
* **Use when** the `/bdbsaastraining` command is invoked.
* **Do NOT use when** performing actual production changes; this is strictly for training.
## Core Process
1. Run Station 0 to interview the trainee and determine their target workload (e.g., WordPress, mailserver).
2. Execute the preflight check script to validate CA and SSH setups.
3. Guide the trainee step-by-step through their specific track without skipping steps.
4. Administer the final exam and generate a PDF certificate upon passing.
## Common Rationalizations
| Rationalization | Reality |
| :--- | :--- |
| "The trainee already knows Docker, so we can skip Incus profile engineering." | Incus has different security paradigms (e.g., unprivileged containers, specific networking); skipping it creates blind spots. |
| "I'll just accept their plain text answer for the exam instead of forcing a multiple-choice selection." | The exam requires strict adherence to multiple-choice formats to maintain grading integrity and track consistency. |
| "The preflight check failed, but I'll let them proceed anyway to save time." | Failing CA/SSH checks means the trainee cannot securely access the cluster, blocking all subsequent hands-on steps. |
## Red Flags
* Skipping Station 0 and directly providing SSH commands.
* Giving the trainee the answers to the exam questions rather than letting them solve them.
* Accepting a failed preflight check without enforcing the corresponding fix.
## Verification
- [ ] Trainee workload track has been explicitly recorded.
- [ ] Preflight script executed with exit code `0`.
- [ ] Final exam scored with a minimum of 80% passing grade.
- [ ] PDF certificate generated and presented to the trainee.
## 🎯 Didaktische Leitphilosophie (gilt in jedem Track)
1. **Station 0 ZUERST.** Beginne NIEMALS mit technischen Aufgaben, bevor du nicht (a) Name, LLDAP-Username und AI-Client erfasst und (b) den Ziel-Workload geklärt und einen Track festgelegt hast.
2. **Station 0.5 (Preflight) vor Station 1.** Lasse den Trainee `scripts/preflight_check.sh` ausführen. Fehlschläge werden zur *Diagnose-Übung mit Fix-Anleitung*, nicht zum stillen Abbruch.
3. **Hands-On vor Theorie.** Max. 1–2 kurze Absätze Erklärung, dann sofort ein realer Befehl mit den persönlichen Daten des Trainees zum Ausführen im Terminal / MCP-Client.
4. **Sokratische Validierung.** Warte immer, bis der Trainee den Befehl ausgeführt und den echten Output gepostet hat. Analysiere den *tatsächlichen* Output, nicht den erwarteten.
5. **Verständnisfragen.** Nach jeder praktischen Übung genau **eine** Multiple-Choice-Frage — im Interaktionsmodus des Clients (siehe `references/interaction-modes.md`). Direktes Feedback mit Begründung.
6. **State-Block.** Hänge an das Ende **jeder** Antwort den Bootcamp-Status-Block an (Format unten).
7. **Keine erfundenen Outputs oder Befehle.** Wenn ein realer Befehl anders reagiert als hier beschrieben, sage das offen und behandle die Abweichung als Lernstoff. Bekannte Gateway-Lücken sind in den Track-Dateien markiert.
---
## 🗣️ Interaktions- & Antwortmodus
Lies **`references/interaction-modes.md`** und wende den Dual-Mode an:
- **Claude Code** → nutze das `AskUserQuestion`-Tool für jede Auswahl (Track-Wahl, Sizing, Prüfungsfragen). „Other" (Freitext) ist immer verfügbar.
- **AGY / Cursor / Claude Desktop / OpenCode / anderer Client** → textuelles A/B/C/D-Schema plus `E) etwas anderes → beschreib es`. Normalisiere Fehleingaben (`b.`, „Antwort B", „die zweite") still zur gemeinten Option.
**Freitext-Regeln:**
- **Station 0, Sizing-Fragen, Zwischenfragen der Stationen:** Freitext ist ausdrücklich *erwünscht* — er ist der Adaptions-Trigger (Track E, Profil-Generierung).
- **Abschlussprüfung (10 Fragen):** Freitext ist *ungültig*. Bittet der Trainee bei einer Prüfungsfrage genau **einmal** um eine Auswahl aus A–D. Bleibt er bei Freitext, ist der Punkt verloren.
---
## 📋 Station 0 — Onboarding & Workload-Interview
Begrüße den Trainee und erfasse in dieser Reihenfolge:
**Teil A — Identität (immer offen/Freitext):**
1. Vollständiger Name (Vor- und Nachname, für das PDF-Zertifikat).
2. Zentraler LLDAP-Benutzername aus der Onboarding-E-Mail (z. B. `noah`, `sarah`, `tkd`).
3. Genutzter AI-Client (Google Antigravity, Cursor, Claude Desktop, Claude Code, OpenCode).
4. Hinweis: Onboarding-E-Mail bereithalten (CA-Fingerprint, Endpunkte, FastMCP-Token-Handshake).
**Teil B — Workload (Auswahl + Freitext):**
> „Was möchtest du auf der BDB SaaS Host Fleet **konkret betreiben**? Danach richte ich dein Training gezielt aus."
| Option | Track | Ziel-Workload |
| :-- | :-- | :-- |
| **A** | `A` | **AI-Agent Sandbox** — autonome Agenten in isolierter, restricted-shell Umgebung |
| **B** | `B` | **WordPress / Web-App** — öffentlich erreichbare Web-Anwendung hinter Caddy + 2FA |
| **C** | `C` | **Mailserver** — Froxlor/Postfix/Dovecot Stack mit eigener Kundendomain |
| **D** | `D` | **Clean Debian / Datenbank / Worker** — generischer System-Container, selbst konfiguriert |
| **E** (Freitext) | `E` | **Etwas anderes** — Trainee beschreibt den Workload; du leitest Ressourcen, Pakete, Ports und Auth-Bedarf im Interview ab |
Speichere intern:
- `<TRAINEE_FULL_NAME>`, `<TRAINEE_USER>`, `<CLIENT_NAME>`
- `<TRACK>` ∈ {A, B, C, D, E}
- Bei Track E zusätzlich das Freitext-Rohziel für `scripts/build_profile.py`.
**Erst wenn Track feststeht:** Lies die zugehörige Datei und folge ihr für die Stationen 2, 3 und 5:
| Track | Datei |
| :-- | :-- |
| A | `references/track-a-ai-agent.md` |
| B | `references/track-b-wordpress.md` |
| C | `references/track-c-mailserver.md` |
| D | `references/track-d-debian.md` |
| E | `references/track-e-custom.md` |
---
## 📋 Station 0.5 — Preflight-Check
Der Trainee führt auf seiner Workstation aus:
```bash
bash ~/.agents/skills/bdbsaastraining/scripts/preflight_check.sh <TRAINEE_USER>
```
*(Pfad an den real installierten Skill-Ort anpassen — Claude Code: `~/.claude/skills/...`, AGY: `~/.gemini/skills/...`.)*
Das Skript prüft: Step-CA CLI, CA-Bootstrap + Fingerprint-Abgleich, `~/.ssh/config` Fleet-Block, FastMCP-Konfig im Client, Erreichbarkeit von `gateway.<DOMAIN>`.
**Bei Fehlern:** Behandle jeden fehlgeschlagenen Check als Mini-Übung. Das Skript gibt für jeden Fehler den Fix-Befehl aus (z. B. `step ca bootstrap …`, `npm run setup:workstation`). Der Trainee führt den Fix aus und wiederholt den Check. Kein Fortschritt zu Station 1, solange Step-CA und SSH-Config nicht grün sind.
**Verständnisfrage 0.5:** Warum bootstrappt `step ca bootstrap` mit einem *Fingerprint* statt blind dem TLS-Zertifikat zu vertrauen?
→ Lösung in `references/exam-pool.md` (`Q_PREFLIGHT`).
---
## 📚 Stationsübersicht
```mermaid
flowchart TD
S0["Station 0: Onboarding + Workload-Interview\n→ Track A/B/C/D/E festlegen"]
S05["Station 0.5: Preflight-Check\n(preflight_check.sh, Diagnose-Übungen)"]
S1["Station 1: Zero-Trust SSH 2FA\n(step ssh login, Zertifikats-Inspektion)"]
+ S1b["Station 1b: Machine Identity (OIDC)\n(RFC 7523 private_key_jwt, Token-Claims & Refresh)"]
S2["Station 2: Incus Profile Engineering\n★ TRACK-SPEZIFISCH: echtes Template inspizieren\n + eigenes Profil bauen (build_profile.py)"]
S3["Station 3: Workload Deployment & Verify\n★ TRACK-SPEZIFISCH: Container starten, Dienst prüfen"]
S4["Station 4: FastMCP Gateway & 4-Augen-Guardrails\n(dein Container, echte Tool-Signaturen, Approval-Dashboard)"]
S5["Station 5: Routing / DNS / Auth\n★ TRACK-SPEZIFISCH: Caddy+CF proxied / DNS-Blueprint / Gateway-Route / keine"]
CERT["🏆 Abschlussprüfung: 6 Kern- + 4 Track-Fragen (≥80%)\n→ PDF-Zertifikat mit Track-Vermerk"]
- S0 --> S05 --> S1 --> S2 --> S3 --> S4 --> S5 --> CERT
+ S0 --> S05 --> S1 --> S1b --> S2 --> S3 --> S4 --> S5 --> CERT
```
---
## 🔹 Station 1 — Zero-Trust SSH 2FA Login & Zertifikats-Inspektion (alle Tracks)
+ > Single Source of Truth für alle Auth-Fakten (Human- und Maschinen-Pfad): `~/.claude/skills/bdbsaashost/SKILL.md` §2. Diese Station lehrt den menschlichen SSH-2FA-Pfad praktisch — die Fakten selbst stehen dort, nicht hier.
+
**Thema:** Kurzlebige, 2FA-signierte SSH-Zertifikate. Warum keine statischen `id_rsa`-Keys.
**Hands-On:**
1. `step ssh login <TRAINEE_USER>` — Browser öffnet sich, Login mit LLDAP-Passwort + WebAuthn/Passkey.
2. Zertifikat inspizieren:
```bash
step ssh inspect ~/.step/ssh/id_ecdsa-cert.pub
```
Trainee liest aus: Gültigkeitsdauer (`Valid: … to …`, ~16 h), Principals (`<TRAINEE_USER>`), CA-Fingerprint.
3. Verbindung testen — nutze den in der **Onboarding-E-Mail** genannten SSH-Endpunkt (den obfuskierten Hostnamen oder die dort genannte IP; frag den Trainee, wenn nicht klar):
```bash
ssh <TRAINEE_USER>@<SSH_ENDPOINT> "id && hostname"
```
**Wenn `ssh` „no such user" oder Permission denied liefert:** Das ist echt und trackrelevant — der zentrale Unix-Account bzw. der Sudo-Eintrag wird nicht automatisch aus LLDAP erzeugt. Halte fest: der Trainee braucht einen Admin, der `useradd` + den `sudoers.d/ldap-admins`-Eintrag setzt. Notiere das als Blocker und fahre mit Station 2 im MCP-Kontext fort, falls SSH nicht verfügbar ist.
**Verständnisfrage 1:** `references/exam-pool.md` → `Q_SSH_TTL`.
---
+ ## 🔹 Station 1b — Machine Identity (OIDC) & Token-Inspektion (alle Tracks)
+
+ > Single Source of Truth für alle Auth-Fakten (Human- und Maschinen-Pfad): `~/.claude/skills/bdbsaashost/SKILL.md` §2. Diese Station lehrt den maschinellen OIDC-Zugangspfad für autonome Agenten — parallel zum menschlichen SSH-2FA-Pfad.
+
+ **Thema:** Asymmetrische Client-Authentifizierung (`private_key_jwt`, RFC 7523), RFC 9068 JWT Profile für OAuth 2.0 Access Tokens und fail-closed Token-Validierung am FastMCP Gateway.
+
+ **Hands-On:**
+ 1. **Machine Credential im OS Keychain prüfen:**
+ ```bash
+ security find-generic-password -s "bdb-saas-host-machine-key" -a "$USER"
+ ```
+ Der private RSA-Schlüssel (2048-bit) wird niemals im Klartext in Config-Dateien abgelegt, sondern sicher im macOS Keychain / OS Secret Store verwaltet.
+ 2. **Client Assertion & Token-Abruf:**
+ Ein signiertes JWT (Client Assertion, RS256) an Authelias Token-Endpunkt (`https://auth.<DOMAIN>/api/oidc/token`) senden und ein kurzlebiges Access Token abrufen:
+ ```bash
+ # Erfolgt im Workflow transparent via bin/setup-workstation.mjs / bin/setup-saas.mjs
+ # Token enthält Claims: iss, sub (client_id), aud, exp, jti, client_id
+ ```
+ 3. **JWT Claims inspizieren:**
+ Token dekodieren (z. B. via `python3 -m jwt <token>` oder Inspektions-Script):
+ Trainee prüft: Gültigkeitsdauer (`exp`, 1 Stunde), `client_id` (z. B. `agent-tkd`), kein Admin-Scope.
+ 4. **Maschinen-API Endpunkt aufrufen:**
+ ```bash
+ curl -s -H "Authorization: Bearer <token>" "https://api.<DOMAIN>/tools/incus_manage_instance"
+ ```
+ Verifizieren: Autorisierter Zugriff auf Tool-Endpunkte; Zugriff auf `/approvals/list` oder Freigabe-Endpunkte wird strikt mit HTTP 404/401 abgewiesen (M6-Isolationsgrenze).
+ 5. **Token-Refresh & Revocation:**
+ Trainee beobachtet: Bei `401 Unauthorized` erneuert der Client das Token einmalig transparent mit einer frischen Assertion. Ein in `queue.db` via `revoked_at` gesperrtes Credential führt sofort zu `invalid_token` (Fail-Closed).
+
+ **Verständnisfrage 1b:** `references/exam-pool.md` → `Q_MACHINE_IDENTITY` & `Q_PRIVATE_KEY_JWT`.
+
+ ---
+
## 🔹 Station 2 — Incus Profile Engineering ★ TRACK-SPEZIFISCH
**Gemeinsamer Rahmen** (Details je Track in der Track-Datei):
1. **Echtes Template inspizieren.** Der Trainee öffnet das reale Profil aus dem Repo (`server-config/templates/incus/profile-*.yaml`) und liest die Struktur: `config.limits.*`, `config.cloud-init.user-data` (#cloud-config), `packages`, `runcmd`, ggf. `write_files`, `devices`.
2. **Eigenes Profil generieren.** Über das Interview + Generator:
```bash
python3 ~/.agents/skills/bdbsaastraining/scripts/build_profile.py \
--track <TRACK> --user <TRAINEE_USER> [weitere Interview-Flags]
```
Das Skript rendert auf Basis des echten Templates ein **valides** Incus-YAML nach `~/profile-<TRACK>-<TRAINEE_USER>.yaml` und zeigt eine Erklärung jeder Zeile. Bei Track E leitet es Ressourcen/Pakete aus dem Freitext ab und warnt bei unplausiblen Werten.
3. **Profil registrieren & prüfen** (auf dem Server, sofern SSH verfügbar):
```bash
sudo incus profile create <TRACK>-<TRAINEE_USER>
sudo incus profile edit <TRACK>-<TRAINEE_USER> < ~/profile-<TRACK>-<TRAINEE_USER>.yaml
sudo incus profile show <TRACK>-<TRAINEE_USER>
```
Hinweis: `incus profile edit` erwartet KEINEN Top-Level `name:` — der Generator lässt ihn weg.
**Verständnisfrage 2:** Track-Datei nennt die passende `Q_*`-ID (Netzwerk-Bridge, cloud-init, rbash, Quotas — je nach Track).
---
## 🔹 Station 3 — Workload Deployment & Verify ★ TRACK-SPEZIFISCH
Gemeinsamer Rahmen:
```bash
sudo incus launch images:debian/13 c-<TRACK>-<TRAINEE_USER> -p default -p <TRACK>-<TRAINEE_USER>
sudo incus list
sudo incus exec c-<TRACK>-<TRAINEE_USER> -- cloud-init status --wait
```
Danach führt die Track-Datei durch die *workload-spezifische* Verifikation (Agent-Task / `curl localhost` / `postconf` / `systemctl` …) und die zugehörige Verständnisfrage.
---
## 🔹 Station 4 — FastMCP Gateway & 4-Augen-Guardrails (alle Tracks)
+ > Single Source of Truth für alle Auth-Fakten (Human- und Maschinen-Pfad): `~/.claude/skills/bdbsaashost/SKILL.md` §2 — dort steht auch, ob/wann sich der Maschinen-Pfad ändert (OIDC-Umbau, `production_artifacts/00_execution_plan.md`).
+
**Thema:** Steuerung über `https://gateway.<DOMAIN>/sse` und die realen Guardrails.
**Hands-On:**
- 1. **MCP-Anbindung prüfen.** Der Token stammt aus dem **Browser-2FA-Handshake** (`npm run setup:workstation` bzw. `npx @hybridlabor-api/bdb-dev-optimized-agent-skills setup-saas`), nicht aus einer E-Mail. Er liegt clientabhängig in `~/.cursor/mcp.json`, `~/Library/Application Support/Claude/claude_desktop_config.json` oder `~/.gemini/antigravity-cli/mcp/bdb_remoteos_gateway/config.json`.
+ 1. **MCP-Anbindung prüfen.** Wie das aktuelle Token erworben wird, steht in `~/.claude/skills/bdbsaashost/SKILL.md` §2 (Single Source of Truth — dieser Fakt ändert sich mit dem OIDC-Umbau, siehe `production_artifacts/00_execution_plan.md`). Das Token liegt clientabhängig in `~/.cursor/mcp.json`, `~/Library/Application Support/Claude/claude_desktop_config.json` oder `~/.gemini/antigravity-cli/mcp/bdb_remoteos_gateway/config.json`.
2. **Status abfragen:** im Client `remoteos_get_system_status()` aufrufen.
3. **4-Augen-Queue provozieren** — echte Signatur (Pflichtfeld `reason`, min. 5 Zeichen):
```
remoteos_manage_instance(
container_name="c-<TRACK>-<TRAINEE_USER>",
action="delete",
reason="Bootcamp Station 4 Guardrail-Demo"
)
```
- Erwartete Antwort: `status: "queued"`, `message: "Guardrail ausgelöst: Freigabe durch <owner> erforderlich."`, `approval_url`, `expires_minutes: 15`.
- 4. **Freigabe.** Die Freigabe läuft über das **Web-Dashboard** `https://gateway.<DOMAIN>/approvals` (Authelia 2FA → Button „Freigeben"). Es gibt **kein MCP-Tool**, das den HMAC-Token selbst zieht. 4-Augen heißt: ein *anderer* Admin (Owner) gibt frei — im Solo-Bootcamp beschreibt der Trainee den Ablauf und ruft danach `remoteos_approval_queue_list()` auf, um den Status `pending` → (nach Freigabe) verschwunden zu sehen.
- 5. **Guardrail-Kontext.** `99-agent-guardrails` gilt für die LDAP-Gruppe `ai_agents`, nicht für menschliche Admins. Für Agenten-Sessions ist der Weg `agent-sudo <command>` mit Auto-Approve für `ls/cat/grep/pwd/whoami/find` und Queue für alles andere.
+ 4. **Freigabe.** Die Freigabe läuft über das **Web-Dashboard** `https://gateway.<DOMAIN>/approvals` (Authelia 2FA → Button „Freigeben"). Es gibt **kein MCP-Tool**, das Freigaben tätigen oder listen kann — alle Approval-Tools wurden zur strikten Wahrung der M6-Grenze aus FastMCP entfernt. 4-Augen heißt: ein *anderer* Admin (Owner) gibt frei. Im Solo-Bootcamp beschreibt der Trainee den Ablauf und prüft den Status über das Dashboard oder den Carve-Out-Endpunkt `GET /api/approvals/{request_id}/status`.
+ 5. **Guardrail-Kontext.** `99-agent-guardrails` gilt für die LDAP-Gruppe `ai_agents`, nicht für menschliche Admins. Für Agenten-Sessions ist der Weg `agent-sudo <command>` mit Auto-Approve für `ls/cat/grep/pwd/whoami` und Queue für alles andere.
**Verständnisfrage 4:** `references/exam-pool.md` → `Q_GUARDRAIL_SCOPE`.
- > **Bekannte Gateway-Lücken (offen dokumentieren, nicht kaschieren):**
- > - `POST /approvals/decide` erwartet einen Query-Param `admin` ohne Default → das MCP-Tool `remoteos_approval_queue_decide` liefert am Remote-Gateway aktuell HTTP 422. Freigabe daher ausschließlich über das Dashboard.
- > - `/tools/add_route` ist am Remote-Gateway derzeit ein Stub (keine echte Caddy-/Cloudflare-Änderung). Siehe Station 5.
+ > **Architektur-Hinweis (M6-Isolationsgrenze):**
+ > - Freigaben erfolgen ausschließlich über das Web-Dashboard mit menschlicher 2FA-Session (Authelia). Sämtliche Approval-Tools im MCP-Server wurden aus Sicherheitsgründen planmäßig ausgemustert.
---
## 🔹 Station 5 — Routing / DNS / Auth ★ TRACK-SPEZIFISCH
| Track | Station-5-Inhalt |
| :-- | :-- |
| A | Interne Gateway-Route für ein Agenten-Web-UI, `require_auth=True` (Authelia forward_auth) |
| B | Öffentliche Web-Route: Caddy `forward_auth` + Cloudflare A-Record 🟠 **proxied** |
| C | **DNS-Blueprint** für die Kundendomain: A/MX/SPF/DKIM/DMARC, Mail-Records ⚪ **DNS-only** |
| D | Optional: interne Route ohne öffentliche Exposition, oder bewusst *keine* Route (nur `incus proxy` Device) |
| E | Aus dem Interview abgeleitet (web → wie B, mail → wie C, intern → wie D) |
Details, Befehle und Verständnisfrage stehen in der jeweiligen Track-Datei. Wo `/tools/add_route` nur den Stub zurückgibt, lässt der Trainee sich zusätzlich mit `remoteos_get_dns_blueprint(...)` (funktioniert real) das DNS-Paket generieren bzw. verifiziert die Caddy-Route direkt auf dem Server (`caddy validate`, `curl -I`).
---
## 🏆 Abschlussprüfung & PDF-Zertifikat
**10 Fragen: 6 Kernfragen (`CORE_1` … `CORE_6`) + 4 Track-Fragen (`<TRACK>_1` … `<TRACK>_4`)** aus `references/exam-pool.md`.
- Bestehensgrenze: **≥ 80 % (8/10)**.
- Prüfungsmodus: A/B/C/D bzw. `AskUserQuestion` ohne „Other"-Wertung. Freitext → einmalige Bitte um Auswahl, sonst 0 Punkte für die Frage.
- Stelle die Fragen einzeln, mit sofortigem Feedback + Begründung nach jeder Antwort.
**Bei ≥ 8/10 — Zertifikat erzeugen:**
```bash
python3 ~/.agents/skills/bdbsaastraining/scripts/generate_certificate.py \
"<TRAINEE_FULL_NAME>" --score <SCORE> --track <TRACK>
```
Das Skript prüft zuerst die Prerequisites (`uv`/`playwright`/Chromium) und gibt bei Fehlen eine klare Install-Anweisung statt eines Tracebacks. PDF landet unter:
`production_artifacts/certificates/BDB_SaaS_Admin_Certificate_<trainee_user>.pdf`
Präsentiere das Zertifikat und gratuliere.
---
## 🔄 State-Management-Engine (an JEDER Antwort)
```text
---
🎓 BDB SAAS BOOTCAMP STATUS
• Trainee: <Vollständiger Name> (<TRAINEE_USER>)
• Client: <CLIENT_NAME> | Modus: <AskUserQuestion | Text-A/B/C/D>
• Track: <A AI-Agent | B WordPress | C Mailserver | D Clean Debian | E Custom>
• Station: <z. B. Station 2 – Incus Profile Engineering>
• Score: <z. B. 3/3 Zwischenfragen (100%) | Prüfung: –>
• Status: <z. B. Warte auf Output von 'incus profile show'>
• Resume-Token: BDB-TRN-<TRACK>-S<Station>-P<Punkte>-<TRAINEE_USER>
---
```
Bei Wiederaufnahme in einem neuen Chat: Frage nach dem Resume-Token, stelle Track + Station daraus wieder her und lies die passende Track-Datei erneut.