Tag 3 · ca. 105 Minuten
„Pro Workflow-Phase" ist der Schlüssel: die Primitive sind keine Sammlung von Gadgets, sondern die Werkzeugleiste zum Phasen-Workflow aus Modul 5.
SKILL.md, Frontmatter, Help-Pfad, Context-Firewall
Analyse, Architecture-Review, Planung, Implementierung
Skills, Rules und Commands für Test, Build, Deploy
Glob-Autoloading statt „bitte lies vorher"
Determinismus statt Bitte — exit-Codes und fail open
Commit & Push ohne Rückfrage, Deploy mit Gate
Clients, Server, Tools, Resources, Prompts, Connectors
Token Overhead & Context Hygiene
Was portabel ist — und was nicht
| Primitiv | Kommt in den Kontext… | Wer entscheidet? | Verbindlich? |
|---|---|---|---|
| CLAUDE.md | immer, bei jedem Aufruf | niemand — ist einfach da | Anweisung, kein Zwang |
| Rule | wenn eine passende Datei angefasst wird (Glob) | das Tool, anhand des Pfads | Anweisung, kein Zwang |
| Skill | wenn Modell oder Mensch ihn aufruft | Modell (Beschreibung) oder Mensch (/name) | Anweisung, kein Zwang |
| Hook | gar nicht — läuft außerhalb des Modells | das Tool, an einem Event | deterministisch erzwungen |
SKILL.mdEin 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.
| Feld | Wirkung | Beispiel aus dem Repo |
|---|---|---|
name | Aufrufname (/name) — nicht zwingend der Ordnername | Ordner architecture-reviewer, name review-architecture |
description | Wofür & wann. Danach entscheidet das Modell, ob es den Skill zieht. | „Use when the user asks to commit changes." |
allowed-tools | Werkzeug-Beschränkung für diesen Skill | Bash(git *) beim commit-Skill |
argument-hint | Erwartete Argumente, wird beim Aufruf angezeigt | [backend | frontend | all] |
disable-model-invocation | true = nur der Mensch darf ihn starten | commit, tag: true |
user-invocable | Als /-Befehl aufrufbar | überall true |
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
## 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.
/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.
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.
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.
Der Phasen-Workflow aus Modul 5 ist die Landkarte. Jede Phase mit Wiederholung und Zeremonie bekommt einen Skill.
| Phase (Modul 5) | Skill bei CGS | Was er abnimmt |
|---|---|---|
| Analyse | /rfcs | RFC vs. Ticket entscheiden, Artefakt anlegen, GitHub-Issue verknüpfen |
| Architecture-Review | review-architecture, ux-reviewer | Prüfung gegen Architektur-Doku und Sensitive-Area-Invarianten |
| Planung | /rfcs update, Command /plan-feature | Status-Gate setzen, RFC in Implementierungsschritte zerlegen |
| Implementierung | generate-tests + Rules (auto) | Testgerüst nach Projektstrategie, Konventionen ohne Nachfragen |
| Delivery | /test → /build → /deploy → /ship | die komplette Release-Kette inkl. Freigabe-Gate |
| Abschluss | /commit, /tag | Commit-Konvention, annotierte Release-Tags |
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 Skill enthält eine Tabelle „RFC + Ticket vs. Ticket-only" — neues Feature, Refactoring, DB-Migration → RFC; Bugfix, UI-Polish → nur Ticket.
allowed-tools erlaubt gh issue und
gh label — sonst nichts von gh.
Kein gh repo delete, kein gh pr merge.
---
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).
---
ux-reviewer
prüft die Kundenoberfläche auf geleakte interne Begriffe. Ein Reviewer pro Blickwinkel.
/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).
/build und /deploy ist bewusst:
Bauen ist wiederholbar, Ausrollen ist es nicht.
Kann vom Modell selbst gezogen werden, hat Frontmatter, Werkzeug-Zaun, Argumente. Trägt die Logik.
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.
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.
„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).
„Das passiert garantiert."
Ein Programm, das das Tool an einem Event startet — außerhalb des Modells. Kein Prompt, keine Wahrscheinlichkeit, kein Vergessen.
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\"" }
] }
]
}
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
"""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", "")
| Exit | PreToolUse | PostToolUse |
|---|---|---|
0 | erlauben — der Call läuft | alles in Ordnung, still |
2 | blockieren, stderr geht ans Modell | Edit ist schon passiert → Nudge ans Modell |
exit 0.
Ein kaputter Wächter darf nie die ganze Arbeit blockieren.
# 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)
ui-theming.md und
migration-safety.md als Prosa stehen — damit ein Verstoß
sofort auffällt statt beim Review oder beim Deploy.
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.
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.
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)
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."""
| Aktion | Freigabe |
|---|---|
| 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 |
"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*)"
]
}
reset --hard, clean -fd,
compose down -v, DROP DATABASE —
alles, was nicht committete Arbeit oder Daten löscht.
Pastebin-Dienste stehen auf deny, damit kein Code oder Secret „mal eben zum Teilen" das Haus verlässt. (Modul 9)
---
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.
Die Anwendung, in der das Modell läuft — hier: Claude Code. Sie verbindet sich zu Servern.
Ein Prozess, der Fähigkeiten anbietet. Lokal gestartet oder remote erreichbar.
Aufrufbare Funktionen mit Parametern — das, was der Agent tatsächlich ausführt.
Lesbare Inhalte, die der Server bereitstellt — Dokumente, Datensätze, Zustände.
Vom Server mitgelieferte Vorlagen, die der Nutzer auswählen kann.
Fertige, gehostete Anbindungen an Dienste — MCP als Produkt statt als Selbstbau.
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
// 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).
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).
Dauerhafte Kontextmiete für alle Tools, auch die nie benutzten. Zahlt sich aus bei Wissen, das der Agent sonst nicht hat.
Kostet nur bei Benutzung. Der Agent kann ohnehin
Bash — und --help lesen.
.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.
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
Skill-Format inkl. Frontmatter-Feldern · Hook-Events und
Registrierung · settings.json-Keys und Permission-Syntax ·
Rule-Autoloading per Glob · Slash-Command-Ablage
Prüffrage fürs eigene Repo: Wenn morgen ein anderes Werkzeug käme — was wäre weg, und was bliebe?
description ist das Interface, allowed-tools der Zaun, der Help-Pfad die Bremse.deny.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.
/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
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