Modul 8

Skills, Tools & Infrastruktur

Tag 3 · ca. 105 Minuten

Lernziel Modul 8

Der Teilnehmer kann Skills, Rules, Commands und Hooks pro Workflow-Phase bauen und das Git-Handling weitgehend autonom gestalten.

„Pro Workflow-Phase" ist der Schlüssel: die Primitive sind keine Sammlung von Gadgets, sondern die Werkzeugleiste zum Phasen-Workflow aus Modul 5.

Inhalt

Skills bauen

SKILL.md, Frontmatter, Help-Pfad, Context-Firewall

Skills pro Phase

Analyse, Architecture-Review, Planung, Implementierung

Delivery-Phase

Skills, Rules und Commands für Test, Build, Deploy

Rules

Glob-Autoloading statt „bitte lies vorher"

Hooks / PostToolUse

Determinismus statt Bitte — exit-Codes und fail open

Autonomes Git-Handling

Commit & Push ohne Rückfrage, Deploy mit Gate

MCP

Clients, Server, Tools, Resources, Prompts, Connectors

MCP vs. CLI

Token Overhead & Context Hygiene

Open Source & Lock-in

Was portabel ist — und was nicht

Vier Primitive, vier Ladezeitpunkte

PrimitivKommt in den Kontext…Wer entscheidet?Verbindlich?
CLAUDE.mdimmer, bei jedem Aufrufniemand — ist einfach daAnweisung, kein Zwang
Rulewenn eine passende Datei angefasst wird (Glob)das Tool, anhand des PfadsAnweisung, kein Zwang
Skillwenn Modell oder Mensch ihn aufruftModell (Beschreibung) oder Mensch (/name)Anweisung, kein Zwang
Hookgar nicht — läuft außerhalb des Modellsdas Tool, an einem Eventdeterministisch erzwungen
Die ersten drei sind Bitten an ein nicht-deterministisches Modell. Nur der Hook ist eine Garantie.

Skills bauen

Anatomie einer SKILL.md

Ein Skill ist ein Ordner mit einer Markdown-Datei: .claude/skills/<ordner>/SKILL.md — YAML-Frontmatter oben, Anleitung für das Modell darunter.

---
name: build
description: Build + push cgsit-finance images to GHCR — either a LOCAL Docker
  build (run inside a subagent so the build logs stay OUT of the main context)
  or by triggering the GitHub CI pipeline. Use when the user wants to
  build/push images (not deploy).
disable-model-invocation: false
user-invocable: true
allowed-tools: Bash(*), Read, Agent, AskUserQuestion
argument-hint: [local | ci [--skip-e2e] | <version>]
---

cgsit-finance/.claude/skills/build/SKILL.md — Frontmatter wörtlich, description gekürzt.

Die Frontmatter-Felder

FeldWirkungBeispiel aus dem Repo
nameAufrufname (/name) — nicht zwingend der OrdnernameOrdner architecture-reviewer, name review-architecture
descriptionWofür & wann. Danach entscheidet das Modell, ob es den Skill zieht.„Use when the user asks to commit changes."
allowed-toolsWerkzeug-Beschränkung für diesen SkillBash(git *) beim commit-Skill
argument-hintErwartete Argumente, wird beim Aufruf angezeigt[backend | frontend | all]
disable-model-invocationtrue = nur der Mensch darf ihn startencommit, tag: true
user-invocableAls /-Befehl aufrufbarüberall true
Diese Felder sind aus den elf Skills in cgsit-finance/.claude/skills/ ausgelesen — sie sind belegt, aber nicht notwendigerweise vollständig. Die offizielle Feldliste vor dem Kurs gegen die Doku prüfen. — geprüft am 2026-07-21

Der Help-Pfad: ein Skill, der nichts tut

## Help (no-op path)
If the argument is `help`, `-h` or `--help`: print ONLY this usage and STOP — run no tests.
> **Usage:** `/test [backend|frontend|all]` — run local unit tests, compact pass/fail.
> • `all` (default) — backend `mvn test` + frontend `ng test` • `backend` / `frontend` — one only
> • e2e is NOT here (CI job). Run before `/build` — the local build does not test.
Ohne diesen Block bedeutet /test help für ein hilfsbereites Modell: „führe die Tests aus und erkläre es dabei". Der No-op-Pfad muss explizit dastehen.

Wörtlich aus cgsit-finance/.claude/skills/test/SKILL.md. Dasselbe Muster in build, deploy, ship.

Skills als Context-Firewall

Ein Skill ist nicht nur eine Anleitung — er ist der Ort, an dem man Output aus dem Hauptkontext heraushält.

## How to run — in a SUBAGENT (context hygiene)

The Maven/Karma output is hundreds of lines. Run each suite in a **subagent**
that returns ONLY a compact result: `{scope, passed, failed, failing_tests[], rc}`.
Do NOT paste raw test logs into the main thread — only the failing-test names
+ the assertion line on failure.
Ein mvn test im Hauptthread kostet den Kontext dauerhaft (Modul 1: nichts fällt raus). Im Subagenten kostet er einmal — zurück kommen fünf Zeilen.

Skills pro Phase

Der Phasen-Workflow aus Modul 5 ist die Landkarte. Jede Phase mit Wiederholung und Zeremonie bekommt einen Skill.

Phase (Modul 5)Skill bei CGSWas er abnimmt
Analyse/rfcsRFC vs. Ticket entscheiden, Artefakt anlegen, GitHub-Issue verknüpfen
Architecture-Reviewreview-architecture, ux-reviewerPrüfung gegen Architektur-Doku und Sensitive-Area-Invarianten
Planung/rfcs update, Command /plan-featureStatus-Gate setzen, RFC in Implementierungsschritte zerlegen
Implementierunggenerate-tests + Rules (auto)Testgerüst nach Projektstrategie, Konventionen ohne Nachfragen
Delivery/test/build/deploy/shipdie komplette Release-Kette inkl. Freigabe-Gate
Abschluss/commit, /tagCommit-Konvention, annotierte Release-Tags

Analyse & Planung: der rfcs-Skill

---
name: rfcs
description: Manage cgsit-finance RFCs and GitHub Tickets. Decide RFC vs
  ticket-only, create/update specs in docs/rfcs/, create/link/close GitHub
  Issues, manage sub-tickets under an RFC.
user-invocable: true
allowed-tools: Read, Edit, Write, Glob, Grep, Bash(ls *), Bash(gh issue *), Bash(gh label *)
argument-hint: [list|status|new "title"|ticket "title"|update NNN status|close NNN]
---

Der Kern ist eine Entscheidung

Der Skill enthält eine Tabelle „RFC + Ticket vs. Ticket-only" — neues Feature, Refactoring, DB-Migration → RFC; Bugfix, UI-Polish → nur Ticket.

Und ein Werkzeug-Zaun

allowed-tools erlaubt gh issue und gh label — sonst nichts von gh. Kein gh repo delete, kein gh pr merge.

Architecture-Review als Skill

---
name: review-architecture
description: Review code changes against the project's architecture definition
  and Sensitive-Area invariants. Use when reviewing PRs, after implementing a
  feature, or as PFLICHT-Subagent-Review in RFC-169 Self-Review Discipline
  (Stripe / Auth / Securities-Core / Portfolio-Ledger / Money /
  Migration-on-Large-Table / Cross-Tenant).
---
Der Skill sagt dem Modell nicht nur was zu prüfen ist, sondern wie der Subagent zu briefen ist: Trigger, geänderte Dateien, Aufgabenkontext, klare Frage — „review against architecture, report per finding".
2026-07-10 Ein UI-Label zeigte „1 Gruppe" — „Gruppe" ist ein internes RBAC-Konzept, kundenseitig existiert nur „Subscriber". Tests waren grün, die Architektur war korrekt, trotzdem war es falsch. Daraus entstand der zweite Review-Skill: ux-reviewer prüft die Kundenoberfläche auf geleakte interne Begriffe. Ein Reviewer pro Blickwinkel.

Delivery-Phase: die Kette

/test
/build
HUMAN
GATE
/deploy
verify

/ship ist die Klammer über alle vier — und lässt das Gate trotzdem stehen:

Chains the three stages into one flow. **The deploy gate is always an
interactive human confirmation** (CLAUDE.md Push & Deploy Policy — deploy is
never autonomous).
Der Schnitt zwischen /build und /deploy ist bewusst: Bauen ist wiederholbar, Ausrollen ist es nicht.

Commands vs. Skills

Skill

Kann vom Modell selbst gezogen werden, hat Frontmatter, Werkzeug-Zaun, Argumente. Trägt die Logik.

Command

Nur vom Menschen per /name. Bei CGS oft nur eine kurze Einstiegs-Anweisung, die auf einen Skill zeigt.

# Review Current Changes

Review the code changes in the current branch against project standards.

1. Run `git diff main --name-only` to see changed files
2. Use the code-reviewer agent (`.claude/agents/code-reviewer.md`) checklist
3. Use the architecture-reviewer skill to check architecture compliance
4. Read `.claude/rules/` for relevant coding rules

Report findings grouped by severity (Critical → Warning → Suggestion).
If everything looks good, say so — don't invent issues.

cgsit-finance/.claude/commands/review.md — wörtlich, gekürzt. Vier Commands im Repo, elf Skills.

Rules & Hooks

Rules: Wissen, das sich selbst holt

Eine Rule ist eine Markdown-Datei unter .claude/rules/ mit Glob-Mustern im Frontmatter. Wird eine passende Datei angefasst, ist die Regel im Kontext — ohne dass jemand daran denkt.

---
globs: ["**/db/migration/**/*.sql",
        "**/db/migration/**/V*.sql",
        "**/src/main/resources/**/V*.sql"]
---

# Flyway Migration Safety (Quarkus + Postgres)

**Auto-loaded** for every `V*.sql` edit. This is the **load-bearing** rule:
a bad migration can put prod into a Flyway crash-loop until the next hotfix,
lock big tables for minutes, or silently corrupt cross-tenant data.

Neun Rules im Repo: java-conventions, quarkus-backend, api-rules, database-rules, testing-rules, angular-conventions, ui-theming, money-fx, migration-safety.

Die Grenze steht wörtlich in der CLAUDE.md: „If you edit a file outside these globs, no rule auto-loads — read the relevant rule file manually." Der Fehlerfall einer Rule ist stumm.

Hooks: bitten vs. garantieren

Skill / Rule / CLAUDE.md

Ich bitte den Agenten darum."

Text im Kontext. Wird meistens befolgt. In der 40. Runde einer langen Session vielleicht nicht mehr (Modul 3: Context Rot).

Hook

Das passiert garantiert."

Ein Programm, das das Tool an einem Event startet — außerhalb des Modells. Kein Prompt, keine Wahrscheinlichkeit, kein Vergessen.

Ein Hook ist das einzige Primitiv, dessen Wirkung nicht davon abhängt, ob das Modell gerade gut drauf ist.

Hooks registrieren: settings.json

"hooks": {
  "PreToolUse": [
    { "matcher": "Bash",
      "hooks": [
        { "type": "command",
          "command": "python3 \"$CLAUDE_PROJECT_DIR/scripts/claude-hooks/block-prod-compose-down.py\"" },
        { "type": "command",
          "command": "python3 \"$CLAUDE_PROJECT_DIR/scripts/claude-hooks/block-parallel-docker-build.py\"" }
      ] }
  ],
  "PostToolUse": [
    { "matcher": "Edit|Write|MultiEdit",
      "hooks": [
        { "type": "command",
          "command": "python3 \"$CLAUDE_PROJECT_DIR/scripts/claude-hooks/postedit-guardrails.py\"" },
        { "type": "command",
          "command": "python3 \"$CLAUDE_PROJECT_DIR/scripts/claude-hooks/rfc-gate-guardrails.py\"" }
      ] }
  ]
}
Belegt sind hier die Events PreToolUse und PostToolUse sowie die Keys matcher, type, command — so stehen sie in cgsit-finance/.claude/settings.json. Es gibt weitere Hook-Events; die vollständige Liste vor dem Kurs in der offiziellen Doku nachschlagen. — geprüft am 2026-07-21

Der Vertrag: stdin, exit-Code, fail open

"""Contract: reads the PreToolUse JSON on stdin. Exit 0 = allow, exit 2 = block
(stderr shown to the model). Fails OPEN on any error so it never blocks
unrelated work."""
try:
    payload = json.load(sys.stdin)
except Exception:
    sys.exit(0)          # fail-open: never block on a parsing hiccup

if payload.get("tool_name") != "Bash":
    sys.exit(0)

cmd = payload.get("tool_input", {}).get("command", "")
ExitPreToolUsePostToolUse
0erlauben — der Call läuftalles in Ordnung, still
2blockieren, stderr geht ans ModellEdit ist schon passiert → Nudge ans Modell
Fail open: jeder Fehler im Hook endet mit exit 0. Ein kaputter Wächter darf nie die ganze Arbeit blockieren.

Ein echter PostToolUse-Hook

# PostToolUse = the edit already happened; this is a **nudge**, not a block.
# Exit 0 = clean/irrelevant, exit 2 = surface the reminder to the model.

fp = payload.get("tool_input", {}).get("file_path", "")

# --- SCSS (cgsit-finance-web) — ui-theming.md ---
if fp.endswith(".scss") and "cgsit-finance-web" in fp:
    for i, ln in enumerate(lines, 1):
        if varfallback.search(ln):
            findings.append(f"  L{i}: var(--cgs-*, <fallback>) — hex-Fallback "
                            f"versteckt fehlende Var im Dark-Mode (ui-theming.md §4.2)")
        elif hexrgb.search(ln):
            findings.append(f"  L{i}: rohe Farbe (#hex/rgb) — via var(--cgs-*) lösen")

if findings:
    sys.stderr.write(f"Guardrail-Grep für {fp} — bitte prüfen (Nudge, kein Block):\n" ...)
    sys.exit(2)
sys.exit(0)
Der Hook führt genau die Greps aus, die in ui-theming.md und migration-safety.md als Prosa stehen — damit ein Verstoß sofort auffällt statt beim Review oder beim Deploy.

Gute Hooks haben ein Datum — und ein Skalpell

2026-07-01 Zwei parallel laufende docker build haben WSL per OOM-Kill beendet. Der /build-Skill baut zwar sequenziell — aber ein beiläufig getipptes docker build umgeht den Skill. → PreToolUse-Hook block-parallel-docker-build.py: blockt einen zweiten Build, solange ein anderer läuft. Der Skill ist die Bitte, der Hook ist das Netz darunter.
2026-07-01 Derselbe Hook-Ansatz produzierte einen Fehlalarm: ein git commit -m "…docker build…" wurde geblockt, weil die Phrase im Text vorkam. → Der Hook prüft seither, ob docker der Ausführende ist (argv0), nicht ob das Wort irgendwo vorkommt.
Produktionsschutz docker compose down löscht auf prod das PostgreSQL-Volume. Ein pauschales Verbot hätte die lokale Entwicklung lahmgelegt. block-prod-compose-down.py blockt nur, wenn drei Bedingungen gleichzeitig zutreffen — siehe unten.
# `docker` must be the EXECUTOR (argv0), not merely a substring in a shell
# that quotes the phrase (git commit -m "...docker build...").
EXEC_BUILD_RE = re.compile(r"^(\S*/)?docker\s+(buildx\s+)?build\b")

# Local dev `docker compose down` is left alone (the dev DB is disposable).
is_executor      = first_token in ("ssh", "docker", "docker-compose")
has_compose_down = re.search(r"docker[-\s]+compose\s+down", low) is not None
targets_prod     = (PROD_EIP in cmd) or ("ssh " in low)

if is_executor and has_compose_down and targets_prod:
    sys.stderr.write("BLOCKED: `docker compose down` on prod deletes the "
                     "PostgreSQL volume — use `up -d --force-recreate`, or `stop`/`start`.")
    sys.exit(2)
Ein guter Hook ist chirurgisch: drei Bedingungen mit UND, lokales Dev bleibt erlaubt — und die Meldung nennt den richtigen Weg, nicht nur ein Verbot.

Was ein Hook nicht kann

Der vierte Hook härtet die RFC-Status-Gates aus Modul 5: behauptet ein RFC den Status Accepted / In Progress / Done, muss das Beweis-Artefakt im Dokument stehen.

"""Was der Hook KANN (Mechanik/Evidenz):
  - Struktur-Lint (Pflichtfelder vollstaendig)
  - Accepted / In Review  -> Analyse-Review-Notiz (+ Datum) vorhanden?
  - In Progress           -> Design-Freigabe-Haken `- [x]` (oder Skip-Begruendung)?
  - Done                  -> Closeout-Notiz (+ Datum) vorhanden?
Was er NICHT kann: das *Urteil* des Reviews ersetzen — das bleibt der
architecture-reviewer-Subagent. Der Hook prueft nur, DASS der Review
dokumentiert ist, nicht ob er gut war."""
Hooks prüfen Mechanik, Subagents fällen Urteile, Menschen tragen Verantwortung. Wer das vermischt, baut entweder Zeremonie oder falsche Sicherheit.

Autonomes Git-Handling — die CGS-Freigabetabelle

AktionFreigabe
Local builds, tests, commits no need to ask
gh run list, Log-Tails, DB-Leseabfragen, Backups proactive OK, just announce
git push origin main no need to ask — push when commits are ready
git push origin main --no-verify ask first
docker compose pull && up -d auf prod ALWAYS ask first
git push --force ALWAYS ask first
Anything destructive ALWAYS ask first
Die Trennlinie ist nicht „gefährlich / harmlos", sondern „reversibel / nicht reversibel". Ein Push nach main ist rückholbar. Ein Deploy trifft echte Nutzer.

Permissions: der deny-Zaun

"permissions": {
  "allow": [ "Read(**)", "Write(**)", "Bash(**)" ],
  "deny": [
    "Bash(rm -rf /)",
    "Bash(git push --force *)",
    "Bash(git reset --hard*)",
    "Bash(git clean -fd*)",
    "Bash(docker compose down -v*)",
    "Bash(*DROP DATABASE*)",
    "Bash(aws rds delete-db-instance*)",
    "Bash(aws s3 rm*--recursive*)",
    "Bash(npm publish*)",
    "Bash(*pastebin*)", "Bash(*transfer.sh*)", "Bash(*file.io*)"
  ]
}

Unwiederbringlich

reset --hard, clean -fd, compose down -v, DROP DATABASE — alles, was nicht committete Arbeit oder Daten löscht.

Exfiltration

Pastebin-Dienste stehen auf deny, damit kein Code oder Secret „mal eben zum Teilen" das Haus verlässt. (Modul 9)

Commit-Konvention als Skill

---
name: commit
description: Create git commits following cgsit-finance project conventions.
  Use when the user asks to commit changes.
disable-model-invocation: true
user-invocable: true
allowed-tools: Bash(git *)
argument-hint: [message or "push"]
---

## Rules
- **NEVER** add "Co-Authored-By" lines
- **NEVER** add "Generated by" or similar AI attribution
- Commit message format: `module: short description`
- Use imperative mood (add, fix, update, remove — not added, fixed)
disable-model-invocation: true — der Agent darf committen, wenn man ihn schickt. Er kommt nicht von selbst auf die Idee, mitten in einer Analyse Historie zu schreiben.

MCP: das Vokabular

Client

Die Anwendung, in der das Modell läuft — hier: Claude Code. Sie verbindet sich zu Servern.

Server

Ein Prozess, der Fähigkeiten anbietet. Lokal gestartet oder remote erreichbar.

Tools

Aufrufbare Funktionen mit Parametern — das, was der Agent tatsächlich ausführt.

Resources

Lesbare Inhalte, die der Server bereitstellt — Dokumente, Datensätze, Zustände.

Prompts

Vom Server mitgelieferte Vorlagen, die der Nutzer auswählen kann.

Connectors

Fertige, gehostete Anbindungen an Dienste — MCP als Produkt statt als Selbstbau.

MCP ist ein offenes Protokoll: ein Server, den ihr einmal baut, funktioniert an jedem Client, der MCP spricht — nicht nur an diesem.
Belegt aus dem CGS-Repo ist ausschließlich der Tools-Teil (Angular-MCP-Server, aufgerufen als mcp__angular__*). Resources, Prompts und Connectors sind hier begrifflich erklärt — Details und Namensgebung vor dem Kurs gegen die offizielle MCP-/Claude-Code-Doku prüfen. — geprüft am 2026-07-21

Ein MCP-Server in der Praxis

// cgsit-finance/.mcp.json
{
  "mcpServers": {
    "angular": {
      "command": "npx",
      "args": ["-p", "@angular/cli", "ng", "mcp"],
      "cwd": "/root/projects/cgsit-finance/cgsit-finance-web"
    }
  }
}
// .claude/settings.local.json — Aktivierung ist ein SEPARATER Schritt
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": [ "angular" ]
.mcp.json ist eine Angebotsliste, keine Einschaltliste. Konfiguriert ≠ aktiv — und im Repo eingecheckt heißt: das ganze Team bekommt dieselbe Angebotsliste (Modul 10).

MCP vs. CLI: Token Overhead

Jeder aktive MCP-Server lädt seine Tool-Definitionen in den Kontext — Namen, Beschreibungen, Parameter-Schemata. Das kostet, bevor irgendetwas passiert, und in jeder Runde erneut (Modul 1: alles wird neu geschickt).

MCP-Server

Dauerhafte Kontextmiete für alle Tools, auch die nie benutzten. Zahlt sich aus bei Wissen, das der Agent sonst nicht hat.

CLI

Kostet nur bei Benutzung. Der Agent kann ohnehin Bash — und --help lesen.

Beleg aus dem Repo Ein GitHub-MCP-Server ist in .claude/.mcp.json konfiguriert — aber enabledMcpjsonServers listet nur angular. GitHub läuft praktisch komplett über die gh-CLI: Bash(gh issue *) im rfcs-Skill, gh run list im Workflow. Wo eine CLI dasselbe kann, ist sie meist billiger — und man kann sie im Skill chirurgisch zuschneiden.

Open Source & Vendor Lock-in

Portabel

RFCs und Specs als Markdown · Architektur- und Domänen-Doku · Tests und Build · CI-Pipeline · Commit- und Review-Konventionen · MCP-Server (offenes Protokoll) · die Arbeitsweise selbst

Toolspezifisch

Skill-Format inkl. Frontmatter-Feldern · Hook-Events und Registrierung · settings.json-Keys und Permission-Syntax · Rule-Autoloading per Glob · Slash-Command-Ablage

Die Wertschöpfung steckt in den portablen Artefakten. Toolspezifisch ist nur die Verdrahtung — und die ist in ein bis zwei Tagen neu gelegt.

Prüffrage fürs eigene Repo: Wenn morgen ein anderes Werkzeug käme — was wäre weg, und was bliebe?

Modul 8 in fünf Sätzen

1Skills sind Markdown mit Frontmatter — die description ist das Interface, allowed-tools der Zaun, der Help-Pfad die Bremse.
2Ein Skill pro Phase, gebaut nach dem dritten manuellen Durchlauf — nicht vorher.
3Rules laden sich per Glob selbst — und schweigen, wenn der Glob nicht passt.
4Hooks sind das einzige deterministische Primitiv: exit 0 erlaubt, exit 2 blockt oder mahnt, jeder Fehler endet fail open. Chirurgisch, nicht pauschal.
5Autonomie nach Reversibilität vergeben: Push autonom, Deploy mit Gate, Unwiederbringliches auf deny.
Alles Gebaute ist nur so viel wert, wie es im Repo steht — versioniert, reviewbar, für alle (Modul 10).

Übung 8 — Skill und Hook bauen

Aufgabe

1. Skill: Baut in seminar-api einen eigenen Skill unter .claude/skills/<name>/SKILL.md mit Frontmatter (name, description, allowed-tools, argument-hint) und einem Help-Pfad, der nichts tut. Vorschlag: /review-slice — prüft den aktuellen Diff gegen eure Konventionen und meldet Findings nach Schweregrad.

2. Hook: Registriert einen PostToolUse-Hook auf Edit|Write, der eine einzige projektspezifische Regel per Grep prüft — z. B. System.out.println in *.java oder ein fehlender @Transactional. exit 0 wenn sauber, exit 2 mit einer Meldung, die den richtigen Weg nennt. Fail open bei jedem Fehler.

Verifizierbares Ergebnis: Beide greifen nachweislich — der Skill wird aufgerufen (per /name und einmal vom Modell selbst, nur über die description), und der Hook meldet sich sichtbar bei einem Edit, der die Regel verletzt — und schweigt bei einem, der sie einhält.

Dauer ca. 35 Minuten · Zweiergruppen

© 2026 CGS IT Solutions GmbH

Alle Rechte vorbehalten

Diese Schulungsunterlagen sind urheberrechtlich geschützt. Vervielfältigung, Weitergabe oder kommerzielle Nutzung — auch in Auszügen — nur mit ausdrücklicher schriftlicher Genehmigung der CGS IT Solutions GmbH.

cgsit-claude-training · Modul 8 · v0.1.0