Migrate all repos into monorepo context folders

Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
2026-06-30 20:39:52 +02:00
parent 2f2b295531
commit a5f8fb49ab
1717 changed files with 447332 additions and 0 deletions
+16
View File
@@ -0,0 +1,16 @@
# Secrets / Credentials — NIE committen
.env
*.key
*.pem
kubeconfig
*-token*
# OS / Editor
.DS_Store
*.swp
.vscode/
.idea/
# Node (für ggf. MCP-Server)
node_modules/
dist/
+307
View File
@@ -0,0 +1,307 @@
DB Inner Source Lizenz Version 1.0
_Fachautoren: Cornelius Schumacher, Schlomo Schapiro (DB Systel GmbH)_
Diese Inner-Source-Lizenz für die Deutsche Bahn („DBISL“) gilt für Werke
(im Sinne der nachfolgenden Begriffsbestimmung), die unter
DBISL-Bedingungen zur Verfügung gestellt werden. Das Werk darf nur in
der durch diese Lizenz gestatteten Form genutzt werden (insoweit eine
solche Nutzung dem Urheber vorbehalten ist).
Das Werk wird unter den Bedingungen dieser Lizenz zur Verfügung
gestellt, wenn der Lizenzgeber (im Sinne der nachfolgenden
Begriffsbestimmung) den folgenden Hinweis unmittelbar hinter dem
Urheberrechtshinweis dieses Werks anbringt:
„Lizenziert unter der DBISL“ oder alternativ „Licensed under the DBISL“
oder in einer anderen Form zum Ausdruck bringt, dass er es unter der
DBISL lizenzieren möchte.
== 1. Begriffsbestimmungen
Für diese Lizenz gelten folgende Begriffsbestimmungen:
* „Lizenz“: diese Lizenz.
* „Originalwerk“: das Werk oder die Software, die vom Lizenzgeber unter
dieser Lizenz verbreitet oder zugänglich gemacht wird, und zwar als
Quellcode und gegebenenfalls auch als ausführbarer Code.
* „Bearbeitungen“: die Werke oder Software, die der Lizenznehmer auf der
Grundlage des Originalwerks oder seiner Bearbeitungen schaffen kann. In
dieser Lizenz wird nicht festgelegt, wie umfangreich die Änderung oder
wie stark die Abhängigkeit vom Originalwerk für eine Einstufung als
Bearbeitung sein muss; dies bestimmt sich nach dem anwendbaren
Urheberrecht
* „Werk“: das Originalwerk oder seine Bearbeitungen.
* „Quellcode“: diejenige Form des Werkes, die zur Auffassung durch den
Menschen bestimmt ist und die am besten geeignet ist, um vom Menschen
verstanden und verändert zu werden.
* „Ausführbarer Code“: die — üblicherweise — kompilierte Form des Werks,
die von einem Computer als Programm ausgeführt werden soll.
* „Lizenzgeber“: die juristische Person innerhalb des DB Konzerns, die
das Werk unter der Lizenz verbreitet oder zugänglich macht.
* „Urheberrechtsinhaber/Autor“: jeder, der bestimmte von ihm selbst
entwickelte oder von Dritten vorgegebene Aufgabenstellungen in ein
Originalwerk umsetzt oder am Originalwerk eine Bearbeitung vornimmt.
* „Bearbeiter“: jeder, der das Werk unter der Lizenz verändert oder auf
andere Weise zur Schaffung einer Bearbeitung beiträgt. Jeder Autor ist
auch Bearbeiter.
* „Lizenznehmer“ („Sie“, „Ihnen“): jede juristische Person innerhalb des
DB Konzerns, die das Werk unter den Lizenzbedingungen nutzt.
* „Verbreitung“ oder „Zugänglichmachung“: alle Formen von Verkauf,
Überlassung, Verleih, Vermietung, Verbreitung, Weitergabe, Übermittlung
oder anderweitiger Online- oder Offline-Bereitstellung von
Vervielfältigungen des Werks oder Zugänglichmachung seiner wesentlichen
Funktionen für dritte natürliche oder juristische Personen.
* „Beitrag“: jedes urheberrechtliche Werk, einschließlich des
Originalwerks sowie jeglicher Änderungen, die der Bearbeiter vornimmt,
und die dem Lizenzgeber bewusst zur Aufnahme in das Werk eingereicht
werden.
* „DB“ oder „DB Konzern“: die Deutsche Bahn AG und alle mit ihr nach §
15 AktG verbundenen Unternehmen.
== 2. Umfang der Lizenzrechte
Der Lizenzgeber erteilt Ihnen hiermit eine weltweite, unentgeltliche,
nicht ausschließliche, unterlizenzierbare Lizenz, die Sie für
Geschäftszwecke des DB Konzerns berechtigt:
* das Werk uneingeschränkt zu nutzen,
* das Werk zu vervielfältigen,
* das Werk zu verändern und Bearbeitungen auf der Grundlage des Werks zu
schaffen,
* das Werk oder Vervielfältigungen davon innerhalb der DB zu verbreiten,
Für die Wahrnehmung dieser Rechte können beliebige, derzeit bekannte
oder künftige Medien, Träger und Formate verwendet werden, soweit das
geltende Recht dem nicht entgegensteht.
Der Lizenzgeber erteilt dem Lizenznehmer ein nicht ausschließliches,
unentgeltliches Nutzungsrecht an seinen Patenten, sofern dies zur
Ausübung der durch die Lizenz erteilten Nutzungsrechte am Werk notwendig
ist.
== 3. Zugänglichmachung des Quellcodes
Der Lizenzgeber kann das Werk entweder als Quellcode oder als
ausführbaren Code zur Verfügung stellen. Stellt er es als ausführbaren
Code zur Verfügung, so stellt er darüber hinaus eine maschinenlesbare
Kopie des Quellcodes für jedes von ihm verbreitete
Vervielfältigungsstück des Werks zur Verfügung, oder er verweist in
einem Vermerk im Anschluss an den dem Werk beigefügten
Urheberrechtshinweis auf einen Speicherort, an dem problemlos und
unentgeltlich auf den Quellcode zugegriffen werden kann, solange der
Lizenzgeber das Werk verbreitet oder zugänglich macht.
== 4. Einschränkungen des Urheberrechts
Es ist nicht Zweck dieser Lizenz, Ausnahmen oder Schranken der
ausschließlichen Rechte des Urhebers am Werk, die dem Lizenznehmer
zugutekommen, einzuschränken. Auch die Erschöpfung dieser Rechte bleibt
von dieser Lizenz unberührt.
== 5. Pflichten des Lizenznehmers
Die Einräumung der oben genannten Rechte ist an mehrere Beschränkungen
und Pflichten für den Lizenznehmer gebunden:
* Inner Source: Der Lizenznehmer darf das Werk ausschließlich für
Geschäftszwecke des DB Konzerns nutzen.
* Urheberrechtshinweis, Lizenztext, Nennung des Bearbeiters: Der
Lizenznehmer muss alle Urheberrechts-, Patent- oder Markenrechtshinweise
und alle Hinweise auf die Lizenz und den Haftungsausschluss unverändert
lassen. Jedem von ihm verbreiteten oder zugänglich gemachten
Vervielfältigungsstück des Werks muss der Lizenznehmer diese Hinweise
sowie diese Lizenz beifügen. Der Lizenznehmer muss auf jedem
abgeleiteten Werk deutlich darauf hinweisen, dass das Werk geändert
wurde, und das Datum der Bearbeitung angeben.
* „Copyleft“-Klausel: Der Lizenznehmer darf Vervielfältigungen des
Originalwerks oder Bearbeitungen nur unter den Bedingungen dieser DBISL
oder einer neueren Version dieser Lizenz innerhalb der DB verbreiten
oder zugänglich machen. Der Lizenznehmer (der zum Lizenzgeber wird) darf
für das Werk oder die Bearbeitung keine zusätzlichen Bedingungen
anbieten oder vorschreiben, die die Bedingungen dieser Lizenz verändern
oder einschränken.
* Bereitstellung des Quellcodes: Wenn der Lizenznehmer
Vervielfältigungsstücke des Werks verbreitet oder zugänglich macht, muss
er eine maschinenlesbare Fassung des Quellcodes mitliefern oder einen
Speicherort angeben, über den problemlos und unentgeltlich so lange auf
diesen Quellcode zugegriffen werden kann, wie der Lizenznehmer das Werk
verbreitet oder zugänglich macht.
* Rechtsschutz: Diese Lizenz erlaubt nicht die Benutzung von
Kennzeichen, Marken oder geschützten Namensrechten des Lizenzgebers,
soweit dies nicht für die angemessene und übliche Beschreibung der
Herkunft des Werks und der inhaltlichen Wiedergabe des
Urheberrechtshinweises erforderlich ist.
== 6. Urheber und Bearbeiter
Der ursprüngliche Lizenzgeber gewährleistet, dass er das Urheberrecht am
Originalwerk innehat oder dieses an ihn lizenziert wurde und dass er
befugt ist, diese Lizenz zu erteilen.
Jeder Bearbeiter gewährleistet, dass er das Urheberrecht an den von ihm
vorgenommenen Änderungen des Werks besitzt und befugt ist, einen Beitrag
unter dieser Lizenz zu erstellen und beizutragen.
Für jeden Fall, in dem der Lizenznehmer die Lizenz annimmt, erteilt der
ursprüngliche Lizenzgeber und alle folgenden Bearbeiter eine Befugnis
zur Nutzung der Beiträge zum Werk unter den Bedingungen dieser Lizenz.
== 7. Gewährleistungsausschluss
Falls die konzerninternen Leistungsbedingungen keine Anwendung finden,
gelten die folgenden Regelungen.
Die Arbeit an diesem Werk wird laufend fortgeführt; es wird durch
unzählige Bearbeiter ständig verbessert. Das Werk ist nicht vollendet
und kann daher Fehler („Bugs“) enthalten, die dieser Art der Entwicklung
inhärent sind.
Aus den genannten Gründen wird das Werk unter dieser Lizenz „so, wie es
ist“ ohne jegliche Gewährleistung zur Verfügung gestellt. Dies gilt
unter anderem — aber nicht ausschließlich — für Marktreife,
Verwendbarkeit für einen bestimmten Zweck, Mängelfreiheit, Richtigkeit
sowie Nichtverletzung von anderen Immaterialgüterrechten als dem
Urheberrecht (vgl. dazu Artikel 6 dieser Lizenz).
Dieser Gewährleistungsausschluss ist wesentlicher Bestandteil der Lizenz
und Bedingung für die Einräumung von Rechten an dem Werk.
== 8. Haftungsausschluss/Haftungsbeschränkung
Falls die konzerninternen Leistungsbedingungen keine Anwendung finden,
gelten die folgenden Regelungen.
Außer in Fällen von Vorsatz oder der Verursachung von Personenschäden
haftet der Lizenzgeber nicht für direkte oder indirekte, materielle oder
immaterielle Schäden irgendwelcher Art, die aus der Lizenz oder der
Benutzung des Werks folgen; dies gilt unter anderem, aber nicht
ausschließlich, für Firmenwertverluste, Produktionsausfall,
Computerausfall oder Computerfehler, Datenverlust oder wirtschaftliche
Schäden, und zwar auch dann, wenn der Lizenzgeber auf die Möglichkeit
solcher Schäden hingewiesen wurde. Unabhängig davon haftet der
Lizenzgeber im Rahmen der gesetzlichen Produkthaftung, soweit die
entsprechenden Regelungen auf das Werk anwendbar sind.
== 9. Zusatzvereinbarungen
Wenn der Lizenznehmer das Werk verbreitet, kann er Zusatzvereinbarungen
schließen, in denen Verpflichtungen oder Dienstleistungen festgelegt
werden, die mit dieser Lizenz vereinbar sind.
Der Lizenznehmer darf Verpflichtungen nur in seinem eigenen Namen
eingehen, nicht jedoch im Namen des ursprünglichen Lizenzgebers oder
eines anderen Bearbeiters, und nur, wenn er sich gegenüber allen
Bearbeitern verpflichtet, sie zu entschädigen, zu verteidigen und von
der Haftung freizustellen, falls aufgrund der von ihm eingegangenen
Gewährleistungsverpflichtung oder Haftungsübernahme Forderungen gegen
sie geltend gemacht werden oder eine Haftungsverpflichtung entsteht.
== 10. Annahme der Lizenz
Der Lizenznehmer stimmt den Bestimmungen dieser Lizenz zu, indem er das
Symbol „Lizenz annehmen“ unter dem Fenster mit dem Lizenztext anklickt
oder indem er seine Zustimmung auf vergleichbare Weise gibt. Das
Anklicken des Symbols gilt als Anzeichen der eindeutigen und
unwiderruflichen Annahme der Lizenz und der darin enthaltenen Klauseln
und Bedingungen.
In gleicher Weise gilt als Zeichen der eindeutigen und unwiderruflichen
Zustimmung die Ausübung eines Rechtes, das in Artikel 2 dieser Lizenz
angeführt ist, wie das Erstellen einer Bearbeitung oder die Verbreitung
oder Zugänglichmachung des Werks oder dessen Vervielfältigungen.
== 11. Informationspflichten
Wenn der Lizenznehmer das Werk verbreitet oder zugänglich macht
(beispielsweise, indem er es zum Herunterladen von einer Website
anbietet), muss der Lizenznehmer über den Vertriebskanal oder das
benutzte Verbreitungsmedium dem Adressatenkreis bzw. der Öffentlichkeit
Mindest-Informationen bereitstellen, üblicherweise bezüglich der
Lizenzgeber, der Lizenz und ihrer Zugänglichkeit, des Abschlusses des
Lizenzvertrags sowie darüber, wie die Lizenz durch den Lizenznehmer
gespeichert und vervielfältigt werden kann.
== 12. Beendigung der Lizenz
Die Lizenz und die damit eingeräumten Rechte erlöschen automatisch, wenn
der Lizenznehmer gegen die Lizenzbedingungen verstößt.
Ein solches Erlöschen der Lizenz führt nicht zum Erlöschen der Lizenzen
von Dritten, denen das Werk vom Lizenznehmer unter dieser Lizenz zur
Verfügung gestellt worden ist, solange diese Personen die
Lizenzbedingungen erfüllen.
== 13. Einreichung von Beiträgen
Sofern nichts ausdrücklich anderes angegeben, unterliegt jeder Beitrag,
den der Lizenzgeber bewusst zur Aufnahme in das Werk eingereicht hat,
den Bedingungen dieser Lizenz, ohne dass zusätzliche Bedingungen gelten.
Ungeachtet des Vorstehenden ersetzt oder ändert keine der hierin
enthaltenen Bestimmungen die Bedingungen einer separaten
Lizenzvereinbarung, die der Auftraggeber möglicherweise mit dem
Auftragnehmer für solche Beiträge abgeschlossen hat.
Für die Länder, in denen Urheberpersönlichkeitsrechte an einem Werk
entstehen können, verzichtet der Urheberrechtsinhaber/Autor im
gesetzlich zulässigen Umfang auf seine Urheberpersönlichkeitsrechte, um
die Lizenzierung der oben aufgeführten Verwertungsrechte wirksam
durchführen zu können.
== 14. Sonstiges
Unbeschadet des Artikels 9 stellt diese Lizenz die vollständige
Vereinbarung der Parteien über das Werk dar.
Es gilt deutsches Recht. Sind einzelne Bestimmungen der Lizenz nach
geltendem Recht nichtig oder unwirksam, so berührt dies nicht die
Wirksamkeit oder Durchsetzbarkeit der Lizenz an sich. Solche
Bestimmungen werden vielmehr dergestalt ausgelegt oder modifiziert, dass
sie wirksam und durchsetzbar sind.
== 15. Gesellschaftsrechtliche Veränderungen
Bei gesellschaftsrechtlichen Veränderungen, z.B. dem Verkauf oder der
Abspaltung einer DB Gesellschaft, gilt folgende Regelungen in Anlehnung
an §12 Beendigungsunterstützung der konzerninternen
Leistungsbedingungen:
Eine weitere Nutzung der lizenzierten Software durch ein nicht mehr dem
DB Konzern angehöriges Unternehmen unterliegt der Zustimmung durch die
Urheber bzw. das CIO Board.
== 16. Lizenzänderungen
Die Urheber eines Werks können gemeinsam eine Änderung der Lizenz
entscheiden, z.B. um das Werk als Open Source Software zu
veröffentlichen. Falls die Urheber nicht verfügbar sind oder sich nicht
einigen können, so kann das CIO Board stellvertretend für alle Urheber
innerhalb der DB die Änderung der Lizenz für ein Werk beschließen.
== 17. Streitbeilegung
Unbeschadet der Regelungen in den konzerninternen Leistungsbedingungen
zwischen den Parteien gilt zwischen den Parteien Folgendes:
Bei Streitigkeiten im Zusammenhang mit der Auslegung und Anwendung
dieser Lizenz, bei denen mehr als ein Konzernunternehmen beteiligt ist,
dient das CIO Board des Konzerns als Entscheidungsgremium, welches von
jeder Partei angerufen werden kann.
== 18. Lizenz der Lizenz
Dieser Lizenztext ist lizenziert unter einer
„https://creativecommons.org/licenses/by/4.0/[Creative Commons
Namensnennung 4.0 International Lizenz]“ (CC-BY 4.0).
Sie dürfen diesen Lizenztext für sich kopieren und anpassen, solange Sie
dabei die Deutsche Bahn Marke und „DB“ nur innerhalb der DB benutzen.
Falls Sie das Material für die Verwendung außerhalb der DB anpassen, so
müssen Sie alle Nennungen der Deutschen Bahn und DB ersetzen bzw.
entfernen. Geänderte Versionen des Lizenztextes müssen klar als
geänderte Versionen kenntlich gemacht werden.
Teile des Textes dieser Lizenz basieren auf der EU Public License (EUPL)
v1.2.
+21
View File
@@ -0,0 +1,21 @@
# #Einfachbahn Kiro-Suite
Zentrale Sammelstelle des **#Einfachbahn**-Teams für wiederverwendbare **Kiro**-Bausteine.
**Sharing is Caring**
## Inhalt
| Ordner | Inhalt |
|--------|--------|
| [`powers/`](powers/) | Kiro Powers (Doku-/Workflow-Wissen, on-demand aktiviert) |
| [`skills/`](skills/) | Kiro Skills (wiederverwendbare Fähigkeiten) |
| [`steerings/`](steerings/) | Steering-Dateien (Kontext/Standards) |
| [`hooks/`](hooks/) | Agent Hooks (Automatisierung bei IDE-Events) |
| [`mcp/`](mcp/) | MCP-Linksammlung (Verweise & Configs, keine Secrets) |
Jeder Ordner hat eine eigene `README.md` mit Details und einer Anleitung „wie füge ich etwas hinzu".
## Beitragen
Baustein im passenden Ordner anlegen, Übersichts-Tabelle der jeweiligen README ergänzen, committen, pushen. **Keine Secrets** committen (Tokens, `.env`, Keys).
@@ -0,0 +1,62 @@
# Hooks
Dieser Ordner sammelt **Kiro Agent Hooks** des Einfachbahn-Teams.
> Was ist ein Hook? Ein Hook startet eine Agent-Ausführung automatisch, wenn ein
> Ereignis in der IDE eintritt (Datei gespeichert, Prompt gesendet, manuell ausgelöst
> usw.).
## Event-Typen (Auswahl)
- `fileEdited`, `fileCreated`, `fileDeleted` — bei Datei-Änderungen
- `promptSubmit` — wenn eine Nachricht an den Agenten gesendet wird
- `agentStop` — wenn eine Agent-Ausführung endet
- `preToolUse` / `postToolUse` — vor/nach Tool-Nutzung (filterbar)
- `preTaskExecution` / `postTaskExecution` — vor/nach Spec-Task
- `userTriggered` — manuell per Button
## Aktionen
- `askAgent` — schickt einen Prompt an den Agenten
- `runCommand` — führt einen Shell-Befehl aus
## Hook-Schema
```json
{
"name": "Lint on Save",
"version": "1.0.0",
"when": {
"type": "fileEdited",
"patterns": ["*.ts", "*.tsx"]
},
"then": {
"type": "runCommand",
"command": "npm run lint"
}
}
```
## Struktur
```
hooks/
├── README.md # diese Datei
└── <hook-name>.kiro.hook # einzelne Hook-Definition (JSON)
```
## Hook hinzufügen
1. Hook-JSON gemäß Schema anlegen.
2. Tabelle unten aktualisieren, committen, pushen.
## Verwenden
Hook über die Kiro-Hook-UI importieren (Command Palette → *„Open Kiro Hook UI"*) oder
die Datei in den Workspace-Hook-Ordner legen.
## Enthaltene Hooks
| Hook | Trigger | Aktion |
|------|---------|--------|
| _(noch keine — gerne ergänzen)_ | | |
+104
View File
@@ -0,0 +1,104 @@
# MCP — Linksammlung
Dieser Ordner ist eine **kuratierte Linksammlung** der vom Einfachbahn-Team genutzten
**MCP-Server** (Model Context Protocol). Hier liegt **kein** Server-Code — nur
Verweise, Endpunkte und Beispiel-Konfigurationen.
> ⚠️ **Keine Secrets committen!** Bearer-Tokens / Personal Access Tokens gehören
> **nicht** ins Repo. In den Beispielen unten stehen ausschließlich Platzhalter wie
> `<TOKEN>`. Echte Tokens nur lokal in `~/.kiro/settings/mcp.json` oder
> `.kiro/settings/mcp.json` eintragen.
## Was ist MCP?
Das Model Context Protocol verbindet Kiro mit externen Tools/Datenquellen über
MCP-Server. Konfiguration erfolgt in `mcp.json` (user-level `~/.kiro/settings/mcp.json`
oder workspace-level `.kiro/settings/mcp.json`).
## DB-interne Server (Taros Playground / DBCS)
| Server | Typ | Endpunkt | Zweck |
|--------|-----|----------|-------|
| `dbctx` | sse | https://taros-playground-dbctx.apps.dbcs-prag.comp.db.de/sse | DB-Kontext-Server |
| `jira` | sse | https://taros-playground-mcp-jira-v2.apps.dbcs-prag.comp.db.de/sse | Jira (read/write) |
| `confluence` | sse | https://taros-playground-mcp-confluence.apps.dbcs-prag.comp.db.de/sse | Confluence (read) |
| `GitLab` | http | https://git.tech.rz.db.de/api/v4/mcp | GitLab API (DB) |
## Öffentliche / paketbasierte Server
| Server | Bezug | Zweck |
|--------|-------|-------|
| `mcp-atlassian` | `uvx mcp-atlassian` | Jira/Confluence über PAT |
| `db-ux` | `npx -y @db-ux/mcp-server@latest` | DB UX Komponenten & Design Tokens |
| `memory-palace` | https://github.com/ (lokaler Build, `dist/index.js`) | Memory-Palace-Notizen |
## Beispiel-Konfiguration (`mcp.json`)
```jsonc
{
"mcpServers": {
"dbctx": {
"type": "sse",
"url": "https://taros-playground-dbctx.apps.dbcs-prag.comp.db.de/sse",
"disabled": false,
"autoApprove": []
},
"confluence": {
"type": "sse",
"url": "https://taros-playground-mcp-confluence.apps.dbcs-prag.comp.db.de/sse",
"headers": {
"Authorization": "Bearer <TOKEN>",
"X-Confluence-Host": "arija-confluence.jaas.service.deutschebahn.com",
"X-Confluence-Mode": "read"
},
"disabled": false,
"autoApprove": []
},
"jira": {
"type": "sse",
"url": "https://taros-playground-mcp-jira-v2.apps.dbcs-prag.comp.db.de/sse",
"headers": {
"Authorization": "Bearer <TOKEN>",
"X-Jira-Host": "arija.jaas.service.deutschebahn.com",
"X-Jira-Mode": "read"
},
"autoApprove": []
},
"GitLab": {
"type": "http",
"url": "https://git.tech.rz.db.de/api/v4/mcp",
"disabled": false,
"autoApprove": []
},
"db-ux": {
"command": "npx",
"args": ["-y", "@db-ux/mcp-server@latest"],
"disabled": false,
"autoApprove": []
},
"mcp-atlassian": {
"command": "uvx",
"args": ["mcp-atlassian"],
"env": {
"CONFLUENCE_URL": "https://arija-confluence.jaas.service.deutschebahn.com",
"CONFLUENCE_PERSONAL_TOKEN": "<TOKEN>",
"JIRA_URL": "https://arija.jaas.service.deutschebahn.com",
"JIRA_PERSONAL_TOKEN": "<TOKEN>"
},
"disabled": false,
"autoApprove": []
}
}
}
```
## Eintrag hinzufügen
1. Server in die Tabelle oben aufnehmen (Name, Typ, Endpunkt/Paket, Zweck).
2. Falls hilfreich: Beispiel-Snippet ergänzen — **mit `<TOKEN>`-Platzhaltern**.
3. Committen, pushen.
## Weiterführend
- Kiro MCP-Doku: https://kiro.dev/docs/mcp/
- `uv`/`uvx` installieren: https://docs.astral.sh/uv/getting-started/installation/
@@ -0,0 +1,70 @@
# Powers
Dieser Ordner enthält **Kiro Powers**: gebündeltes Dokumentations-/Workflow-Wissen,
das Kiro bei passenden Anfragen automatisch aktiviert.
> Was ist eine Power? Eine Power verpackt Wissen (`POWER.md`), optionale
> Workflow-Guides (`steering/*.md`) und optional MCP-Server. Kiro lädt die
> Detail-Instruktionen erst bei Bedarf („on-demand") — das hält den Kontext schlank.
## Enthaltene Powers
| Power | Zweck | Aktiviert bei Themen wie |
|-------|-------|--------------------------|
| [`db-openshift-deploy`](db-openshift-deploy/) | Manuelles Deployment: Docker → Artifactory → OpenShift (`oc`) | openshift, oc, dbcs, artifactory, image pull |
| [`db-pipeship-onboarding`](db-pipeship-onboarding/) | Repo mit pipeship aufsetzen (CI/CD bis Prod, K8s, Trivy, Renovate) | pipeship, gitlab ci, deploy_k8s_generic, cdaas |
| [`db-dxp-platform`](db-dxp-platform/) | Nachschlagewerk DXP-Ökosystem (pipeship, CDaaS, Portal, Compliance) | dxp, developer portal, crossplane, flux, tenant |
| [`db-scm-info-compliance`](db-scm-info-compliance/) | `scm-info.yaml` erstellen/validieren + Compliance-Checks | scm-info, compliance suite, beam id, sbom |
Jede Power liegt in einem eigenen Ordner mit einer `POWER.md` (Pflicht); manche
haben zusätzlich `steering/`-Dateien für vertiefende Workflows.
```
powers/
├── README.md # diese Datei
├── db-openshift-deploy/
│ └── POWER.md
├── db-pipeship-onboarding/
│ ├── POWER.md
│ └── steering/
│ └── repo-typen.md
├── db-dxp-platform/
│ └── POWER.md
└── db-scm-info-compliance/
└── POWER.md
```
## Installation (lokal testen)
Powers werden über die **Powers-UI** in Kiro installiert:
1. **Powers-Panel öffnen**: Powers-Icon in der Kiro-Sidebar — oder Command Palette →
*„Powers"* — oder Kiro bitten: „Open the powers configuration".
2. **„Add Custom Power"** klicken.
3. **„Local Directory"** wählen.
4. **Absoluten Pfad** zum gewünschten Power-Ordner einfügen, z. B.:
```
<PFAD-ZUM-REPO>/powers/db-pipeship-onboarding
```
(Pro Power einmal — der Pfad zeigt auf den Ordner, der die `POWER.md` enthält.)
5. **„Add"** klicken. Die Power erscheint unter *Installed Powers* (Status „Active").
> **Wichtig:** Der Pfad muss **auf den einzelnen Power-Ordner** zeigen (mit `POWER.md`
> direkt darin), **nicht** auf `powers/`.
## Teamweite Verteilung
Da dieses Repo ein Git-Repo ist, können die Powers auch als **Repository-Quelle** in
Kiro hinterlegt werden — dann installiert das Team sie direkt aus Git statt über lokale
Pfade. In der Powers-UI eine Custom-Repository-Quelle mit der Repo-URL und dem Pfad
`powers/<power-name>` hinzufügen.
## Eigene Power hinzufügen
1. Neuen Ordner `powers/<name>/` anlegen.
2. `POWER.md` mit Frontmatter (Name, Beschreibung, Keywords) + Inhalt erstellen.
3. Optional `steering/*.md` für vertiefende Workflows ergänzen.
4. Diese Tabelle oben aktualisieren, committen, pushen.
Mehr zum Bauen eigener Powers: https://kiro.dev/docs/powers/ — sowie die offizielle
Power **„Build a Power"** (`power-builder`) in der Kiro-Powers-Registry.
@@ -0,0 +1,100 @@
---
name: "db-dxp-platform"
displayName: "DB DXP Platform Guide"
description: "Nachschlagewerk zum DB Developer Experience Platform (DXP) Ökosystem: pipeship, CDaaS GitLab Runner, Developer Portal (Tenants, GitOps/Flux, Crossplane), Compliance Suite und DBCS/Kubernetes-Integration. Erklärt, was die Bausteine sind und wie sie zusammenspielen."
keywords: ["dxp", "developer portal", "pipeship", "cdaas", "compliance suite", "dbcs", "backstage", "crossplane", "flux gitops", "tenant"]
author: "einfachbahn-lab"
---
# DB DXP Platform Guide
## Overview
Diese Knowledge-Base-Power erklärt das Ökosystem der **Developer Experience Platform (DXP)**
der DB Systel (Teil von *build IT*). Sie beantwortet Fragen wie „Was ist pipeship/CDaaS?",
„Wofür brauche ich einen Tenant?", „Wie hängen Developer Portal, GitOps und Crossplane
zusammen?". Für die konkrete Repo-Initialisierung mit pipeship siehe die Power
**DB pipeship Onboarding**.
## Die Bausteine
| Produkt | Zweck |
|---------|-------|
| **pipeship** | Pipeline-as-a-Service: fertige, DB-konforme GitLab-CI/CD-Pipeline-Module (per `include` aus Artifactory) |
| **CDaaS** | Continuous-Delivery-as-a-Service: gehärtete GitLab Runner (Shared, Base/Multi-Tenant, selfhosted für AWS/k8s/OpenShift) |
| **Developer Portal** | Self-Service-Oberfläche (Backstage) für Tenants, Templates, Integrationen, Status, Compliance |
| **Compliance Suite** | Scannt Repos auf Secrets, Schwachstellen, Lizenzen; erstellt SBOMs |
| **DBCS** | DB Container Services: OpenShift-Cluster + KAS (Kubernetes-as-a-Service) |
Gemeinsame Tool-Basis: **GitLab, Artifactory, CDaaS, OpenShift (DBCS)**.
## Zentrale URLs
- Developer Portal: https://db.de/dxp · https://dp.dxc.comp.db.de
- pipeship: https://db.de/pipeship
- CDaaS: https://db.de/cdaas
- DBCS: https://db.de/dbcs
- Compliance Findings: https://dp.dxc.comp.db.de/compliance/repositories
- Kubernetes-UI Headlamp: https://headlamp.dxc.comp.db.de
- GitLab: https://git.tech.rz.db.de · Artifactory: https://bahnhub.tech.rz.db.de
- Digitalshop: https://dbdigitalshop.service-now.com/digitalshop
## Kernkonzepte
### DXP Mandant (Tenant)
Logische Einheit im Developer Portal, die alle Ressourcen einer **Anwendung** bündelt
(nicht teamorientiert). Verwaltet Rollen, Kostenstellen, Integrationen zentral; Repos erben
die Konfiguration. Jeder Tenant erhält den K8s-Namespace `p-{tenant-name}-tenant` mit
AGE-Key, Metadata/Environment-Ressourcen, ServiceAccount/RoleBinding und Crossplane-XRs.
Bestellung einmalig kostenfrei im Digitalshop (kostenpflichtig nur deployte Ressourcen).
### Provisionierung: Crossplane + FluxCD (GitOps)
- Zielzustand liegt als YAML im **GitOps-Repo** (`tenant-information`).
- **Flux** reconciled asynchron (kein direkter Effekt beim Push wie bei Pipelines).
- **Crossplane** provisioniert die Ressourcen (DBMC-Datenbanken, DBCS-Namespaces, Artifactory).
- **Software-Templates** (Backstage Scaffolder) scaffolden komplette App-Repos inkl.
pipeship-Pipeline, K8s-Namespace, DB und CDaaS-Runner.
```mermaid
flowchart TB
DP[Developer Portal<br/>Backstage] -->|Tenant + Templates| GR[GitOps-Repo<br/>tenant-information]
GR -->|Flux reconcile| CP[Crossplane]
CP --> NS[K8s-Namespace DBCS]
CP --> DB[(DBMC-Datenbank)]
CP --> AF[Artifactory-Registries]
```
### Rollen (Least Privilege)
`managers` (fachlich, entscheiden über Zugriff/Metadata), `owners` (technisch, Integrationen),
`developers` (i. d. R. Lese-, je Integration Schreibrechte), `readers` (nur einsehen).
Pro Rolle wird automatisch eine **ACAT-Gruppe im BKU AD** erzeugt. Besteller wird Manager.
### CDaaS Runner-Varianten
- **Shared Agent**: geteilte GitLab Shared Runner (Fair-Use, nur kleine Pipelines), Tag `cdaas-shared-agent`.
- **Base Runner (Beta)**: zentral, mandantenfähig, Pay-per-Use; Tags z. B. `build-base-runner`, `prod-base-runner`. Sicherheit über **Cred&Gator** (Berechtigung an Pipeline gebunden, nicht an Runner).
- **Selfhosted Agents**: Helm (k8s/OpenShift) oder CDK-Library (AWS), im eigenen Namespace/Account.
### Compliance Suite (Scanner)
- **Secrets (Betterleaks)**, **Dependencies (Syft+Grype)**, **DB Compliance** (Projekteinstellungen, README/LICENSE/scm-info.yaml), **Licenses (Grant)**.
- Wöchentliche Scans (Di/Do/Sa 18:00), Dependency-Checks alle 12 h. SBOM bei jedem Scan.
- Basisscans kostenlos; Ergebnisse im Developer Portal.
### DBCS/Kubernetes-Integration
- Namespaces (OpenShift „Projects") werden als `Project`-Ressource (`kas.dp.db.de/v1alpha1`) im GitOps-Repo beschrieben.
- `pipeshipSupport: true` legt automatisch Secrets an (`artifactory-stage/-read/-release`, `docker-pull-secret`, `gitlab-user`/`gitlab-test-user`).
- **OpenShift unterstützt keine Wildcards** in docker-pull-secrets → Registries explizit in `customDockerRepos` deklarieren.
- Cluster-Inspektion für Advanced User über **Headlamp** (SSO) oder das Kubernetes-Plugin im Portal.
## Häufige Fragen
- **„pipeship oder CDaaS?"** — pipeship liefert die Pipeline-Logik (Jobs/Module), CDaaS die Runner, auf denen sie läuft. pipeship baut auf CDaaS auf.
- **„Brauche ich einen Tenant?"** — Für GitOps-Provisionierung (DBMC/DBCS) und pipeship-Onboarding ja. Nur um Compliance-Findings zu sehen: nein.
- **„Wo liegt was?"** — Grundkonfiguration im Portal-UI; Infrastruktur-YAML im GitOps-Repo; Schnellstart über Software-Templates.
## Best Practices
- Updates zeitnah (Empfehlung ≤ 14 Tage), automatisiert via **Renovate** → bleibt compliant.
- Gruppennamen GitLab = Artifactory-Team-Name, nur Kleinbuchstaben/Zahlen.
- Vor `pipeshipSupport: true` vorhandene Secrets (`pipeship-secrets`, age/GPG-Keys) sichern — werden überschrieben.
## Weiterführend
Vollständige Wissensbasis im Repo `einfachbahn-lab/doku/deployment-doku`, Datei
`docs/08-dxp-plattform.md`. Doku-Quellen (DB-Login nötig): `git.tech.rz.db.de/pipeship/docs/docs-as-code`,
`.../devex-core/buildit-docu`, `.../cdaas/documentation`.
@@ -0,0 +1,130 @@
---
name: "db-openshift-deploy"
displayName: "DB OpenShift Deploy"
description: "Manuelles Deployment im DB-Konzern: Docker-Image bauen, ins Artifactory (jFrog/bahnhub) pushen und auf einem OpenShift-Cluster (DBCS) per oc deployen. Inklusive Secrets, Image-Pull-Secret und Troubleshooting."
keywords: ["openshift", "oc cli", "dbcs", "artifactory", "bahnhub", "docker image", "kubernetes deployment", "image pull secret", "imagepullbackoff"]
author: "einfachbahn-lab"
---
# DB OpenShift Deploy
## Overview
Diese Power bündelt das Wissen, um eine containerisierte Anwendung im DB-Konzern
**manuell** auf einem OpenShift-Cluster (DB Container Services, DBCS) zu betreiben:
Image mit Docker bauen, ins **Artifactory** (`bahnhub.tech.rz.db.de`) pushen und mit
`oc apply` deployen. Ideal für Prototypen, Labs und kleine Services. Für den
standardisierten, compliance-konformen Weg siehe die Power **DB pipeship Onboarding**.
## Onboarding
### Voraussetzungen
- **DeBi-Account** (SSO für Git, Artifactory, OpenShift). Für GitLab ist zusätzlich eine Bestellung im Digitalshop nötig.
- **Docker Desktop** (Image-Build)
- **`oc` CLI** (OpenShift-Client; aus der Console: `?`*Command Line Tools*)
- Ein **Docker-Repo im Artifactory** (einmalig über Self-Service https://bass.tech.db.de/welcome beantragen)
- **Artifactory-API-Key**: https://bahnhub.tech.rz.db.de → Profil → *Edit Profile* → API Key
### Wichtige Links
- Artifactory Self-Service: https://bass.tech.db.de/welcome
- jFrog Artifactory: https://bahnhub.tech.rz.db.de/ui/packages
- GitLab: https://git.tech.rz.db.de/
- OpenShift Console (Beispiel): https://console-openshift-console.apps.dbcs-riga.comp.db.de/
## Key Concepts
| Begriff | Bedeutung |
|---------|-----------|
| Image | Unveränderliches Paket aus App + Abhängigkeiten + Laufzeit |
| Registry | Image-Speicher — hier Artifactory `bahnhub.tech.rz.db.de` |
| OpenShift | Enterprise-Kubernetes von Red Hat (= k8s + Console, `oc`, `Route`, strenge SCC) |
| Deployment | Beschreibt den Pod (Image, Env, Ressourcen, Health-Checks) |
| Service | Cluster-interne stabile Adresse |
| Route | OpenShift-Objekt: HTTPS-Zugang von außen (TLS-Termination) |
| PVC | Persistenter Speicher, überlebt Pod-Neustarts |
## Common Workflows
### 1. Image bauen + pushen
**Immer `--platform linux/amd64`** (auch auf Apple Silicon), Base-Images aus dem
Artifactory-Mirror (kein Docker-Hub-Direktzugriff im Cluster).
```bash
docker login einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de # User=DeBi, Pass=API-Key
docker build --platform linux/amd64 \
-t einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/api-viewer:0.8.0 .
docker push einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/api-viewer:0.8.0
```
### 2. Erst-Setup im Namespace
```bash
# Am Cluster anmelden (öffnet SSO im Browser)
oc login https://api.dbcs-riga.comp.db.de:6443
# Image-Pull-Secret (sonst ImagePullBackOff)
oc create secret docker-registry artifactory-pull -n einfachbahn-dev \
--docker-server=einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de \
--docker-username=DEIN_USER --docker-password=DEIN_API_KEY
# App-Secret (vertrauliche Werte)
oc create secret generic babedas-api-viewer -n einfachbahn-dev \
--from-literal=AUTH_USER=... --from-literal=AUTH_PASS=...
```
### 3. Deployen
Manifeste mit Platzhaltern `<NAMESPACE>`, `<REGISTRY>`, `<TAG>` ersetzen und anwenden
(Reihenfolge: pvc → deployment → service → route):
```bash
for m in k8s/pvc.yaml k8s/deployment.yaml k8s/service.yaml k8s/route.yaml; do
sed -e "s|<NAMESPACE>|einfachbahn-dev|g" \
-e "s|<REGISTRY>|einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de|g" \
-e "s|<TAG>|0.8.0|g" "$m" | oc apply -f -
done
oc rollout status deployment/api-viewer -n einfachbahn-dev
```
### 4. Betrieb / Diagnose
```bash
oc get pods -n einfachbahn-dev -l app=api-viewer
oc logs -f deployment/api-viewer -n einfachbahn-dev | grep -v "GET /"
oc exec -it deployment/api-viewer -n einfachbahn-dev -- sh
oc set env deployment/api-viewer -n einfachbahn-dev FETCH_ON_START=true
oc delete pod -l app=api-viewer -n einfachbahn-dev # Neustart nach Secret-Änderung
```
## OpenShift-Besonderheiten (wichtig)
- **Non-root**: Container laufen mit zufälliger UID. Schreib-Verzeichnisse weltbeschreibbar machen (`chmod 777 /app/data`), unter `/app` statt `/`.
- **`restricted` SCC**: `privileged: false`, `runAsNonRoot: true`. Kein Docker-in-Docker.
- **Kein Internet**: Images nur aus Artifactory-Mirror (`docker-hub-remote.bahnhub.tech.rz.db.de`).
- **`Route` statt `Ingress`** für externen HTTPS-Zugang.
## Troubleshooting
### Pod: `ImagePullBackOff`
Image-Pull-Secret `artifactory-pull` fehlt/falsch, oder Image-Tag existiert nicht. Secret neu anlegen, Tag prüfen.
### Pod: `CreateContainerConfigError`
App-Secret fehlt oder ein referenzierter Key existiert nicht.
### `exec format error` / sofortiger Crash
Falsche Architektur — mit `--platform linux/amd64` neu bauen.
### `docker push` → `unauthorized` / `denied`
Nicht eingeloggt (`docker login`) oder kein Push-Recht/Repo fehlt (Self-Service prüfen).
### 502 Bad Gateway
Pod noch nicht `ready` — Logs prüfen, warten.
### Daten weg nach Redeploy
PVC prüfen: `oc get pvc -n einfachbahn-dev` (sollte erhalten bleiben).
## Best Practices
- Feste, semantische Tags (`0.8.0`), kein `latest` für Deployments → nachvollziehbare Rollbacks.
- Health-Checks (`livenessProbe`/`readinessProbe` auf `/health`) im Deployment.
- Keine Secrets im Image oder Git — immer als OpenShift-Secret.
- PVC niemals beim Aufräumen mitlöschen, wenn Daten erhalten bleiben sollen.
## Weiterführend
Vollständige Doku, Scripts (`build-and-push.sh`, `deploy.sh`, `create-secret.sh`) und
k8s-Manifest-Templates im Repo `einfachbahn-lab/doku/deployment-doku` (`docs/01``docs/07`,
`scripts/`, `k8s/`).
@@ -0,0 +1,133 @@
---
name: "db-pipeship-onboarding"
displayName: "DB pipeship Onboarding"
description: "Schritt-für-Schritt-Anleitung, um ein GitLab-Repo im DB-Konzern mit pipeship aufzusetzen: Group- und Project-Onboarding, deploy_k8s_generic nach OpenShift/DBCS, CI/CD-Secrets (SOPS/age), Trivy-Container-Security, Container-Annotations und Renovate-Updates."
keywords: ["pipeship", "gitlab ci", "deploy_k8s_generic", "cdaas", "renovate", "sops age", "trivy", "dbcs onboarding", "cloud native buildpacks"]
author: "einfachbahn-lab"
---
# DB pipeship Onboarding
## Overview
Diese Power führt durch das Aufsetzen eines **Code-Repos** mit **pipeship**
(Pipeline-as-a-Service der DB Systel): vom Group-/Project-Onboarding über das
pipeship-Produkt `deploy_k8s_generic` (Build → Test → Deploy nach OpenShift/DBCS)
bis zu CI/CD-Secrets, Container-Security (Trivy) und automatischen Updates via Renovate.
Ergebnis ist eine vollautomatische, **compliance-konforme** CI/CD-Pipeline.
Für das Hintergrundwissen zum Ökosystem siehe die Power **DB DXP Platform Guide**.
Für `scm-info.yaml`-Details die Power **DB scm-info & Compliance**.
## Onboarding (Voraussetzungen)
- Zugriff auf GitLab (`git.tech.rz.db.de`), Artifactory (`bahnhub`), Cloud-/K8s-Provider
- **DXP Mandant** (Digitalshop), GitLab-Gruppe via **GroupTrust** verbunden, GitOps-Repo (`tenant-information`)
- **pipeship CLI**: `brew tap dbsystel/pipeship https://git.tech.rz.db.de/pipeship/toolbox/homebrew.git && brew install pipeship-cli`
- Zusätzlich `kubectl`, `oc`, `sops`, `age` → prüfen mit `pipeship dependency`
> Schnellster Weg: Im Developer Portal das Software-Template **„DBCS project with CDaaS agent"**
> (`dbcs-with-cdaas`) bzw. ein kombiniertes Template, das Repo + Pipeline + Namespace + Runner erzeugt.
## Prinzipien von pipeship
- **Reference instead of copy**: Pipelines per GitLab `include` einbinden (kein Copy&Paste).
- **Update at your own pace**: Updates kommen als Merge Requests (Renovate).
- **Convention over Configuration**: Standard-Pipeline pro Use-Case, anpassbar.
- Baut auf GitLab Auto DevOps + Buildpacks auf.
## Onboarding-Fluss
```
GROUP-ONBOARDING (einmal pro Top-Level-GitLab-Gruppe)
Artifactory-Registries (BASS) · CDaaS-Runner · (SonarQube) · CI/CD-Secrets → "pipeship it!"
PROJECT-ONBOARDING (pro Repo)
Compliance herstellen · Include injizieren · Renovate einrichten
```
## Common Workflows
### 1. Basis-Compliance herstellen
- `scm-info.yaml` (Endung **`.yaml`**, schema-valide, Beam-ID), `README.md`, `LICENSE` → Template `init-app-general`
- Default-Branch schützen: `Settings ➞ Repository ➞ Protected Branches`
- Tags per Wildcard `*.*` schützen (Format `major.minor`, z. B. `1.2`)
### 2. K8s-Namespace + CDaaS-Runner (GitOps)
Template `dbcs-with-cdaas` → MR ins `tenant-information`-Repo. Mit `pipeshipSupport: true`
werden alle nötigen Secrets automatisch im Namespace angelegt:
```yaml
apiVersion: kas.dp.db.de/v1alpha1
kind: Project
metadata:
name: myapp-prod
namespace: p-<tenant>-tenant
spec:
cluster: riga # prag für prod
environment: prod
pipeshipSupport: true
customDockerRepos: # OpenShift kennt keine Wildcards
- "myteam-docker-release-local.bahnhub.tech.rz.db.de"
```
### 3. CI/CD-Secrets verschlüsseln (falls nötig)
Secrets **nie im Klartext** in GitLab (ADR-18). age-/PGP-Keys liegen im Namespace (K8s) bzw. KMS (AWS).
Lokal mit **SOPS + age** verschlüsseln, verschlüsselt committen — pipeship entschlüsselt zur Laufzeit
und exportiert als Umgebungsvariablen. (Beim CDaaS Shared Agent stattdessen `secrets.yaml` mit GPG-`PGP MESSAGE` und Tag `cdaas-shared-agent`.)
### 4. pipeship-Pipeline injizieren
Template **pipeship Pipeline Onboarding** → Vendor `pipeship`, Produkt **`deploy_k8s_generic`**,
Release-Channel (z. B. `resolved/release` oder `baserunner/release`), Zielprojekt → MR mergen.
Ergebnis `.gitlab-ci.yml`:
```yaml
---
include:
- https://bahnhub.tech.rz.db.de/artifactory/pipeship-generic-release-local/release/products/deploy_k8s_generic/<version>.yaml
variables:
DK8G_K8S_TAG: "kubernetes"
DK8S_HELM_REMOTE_VALUES: |
https://bahnhub.tech.rz.db.de/artifactory/pipeship-generic-release-local/values-library/1.1.119/tmp-volume.yaml
run_unit_tests:
image: <image-mit-test-framework>
script:
- <test-script>
```
**Build-Verhalten:** Dockerfile vorhanden → wird genutzt; kein Dockerfile → **Cloud Native Buildpacks** (ADR-23).
Image wird in Artifactory promoted und in die K8s-Stages deployt.
### 5. Container-Security & Compliance
- **pipeship-Images** werden vom pipeship-Team per **Trivy/AquaSec** gescannt → du bist compliant, **solange du aktuell hältst** (≤ 14 Tage, Renovate).
- **Eigene/überschriebene Images** → Risikobewertung liegt bei dir (selbst scannen/Restrisikodeklaration).
- **SBOM**: Job `generate_image_sbom_syft`; Compliance Suite scannt Dependencies/Lizenzen.
- **read-only securityContext** per Default (Schreibpfade als Volume mounten).
- **Annotations** (Beam-ID, Contacts) automatisch aus `scm-info.yaml` (`GA_REFERENCE_ID`, `GA_CONTACT`).
### 6. Updates aktivieren (Renovate)
Template **pipeship Renovate Starter** + Preset:
```json
{ "extends": ["local>renovate/renovate-presets:pipeship", "local>renovate/renovate-presets:pipeship-group"] }
```
Release-Channels (über Include-URL bestimmt): `canary`, `release`, `resolved/...`, `baserunner/...`.
## Definition of Done (Code-Repo)
- [ ] `scm-info.yaml` (.yaml, valide, Beam-ID), `README.md`, `LICENSE`
- [ ] Default-Branch + Tags (`*.*`) protected
- [ ] DXP Mandant + GitLab-Gruppe (GroupTrust) + GitOps-Repo
- [ ] Artifactory-Registries (Naming-Konvention), CDaaS-Runner
- [ ] DBCS-Namespace mit `pipeshipSupport: true`
- [ ] `.gitlab-ci.yml` mit `deploy_k8s_generic` + Unit-Test-Job
- [ ] CI/CD-Secrets verschlüsselt (age/SOPS/KMS), nichts im Klartext
- [ ] read-only securityContext + Container-Annotations
- [ ] SBOM-Job aktiv, Findings geprüft
- [ ] Renovate-Preset aktiv
## Available Steering Files
- **repo-typen** Setup-Matrix für Code / Doku / Architektur / Konzept-Repos (welche Bausteine wann nötig sind, inkl. `deploy_pages_generic` für Doku/Architektur).
## Troubleshooting
- **Pipeline triggert nicht** → Tag matcht nicht das geschützte Wildcard (`*.*`, Format `major.minor`).
- **Include nicht auflösbar** → Registry-Naming/Anonymous-Scope prüfen; Channel-URL korrekt?
- **`pipeship dependency` schlägt fehl** → `sops`/`age`/`kubectl`/`oc` nachinstallieren.
- **Secret im Pipeline-Log sichtbar** → entschlüsselte env-Vars nie ungefiltert ausgeben.
- **Renovate erkennt Updates nicht** → pipeship-Preset (Regex-Manager) fehlt.
## Weiterführend
Vollständiger Praxis-Guide im Repo `einfachbahn-lab/doku/deployment-doku`, Datei
`docs/09-pipeship-setup-guide.md` (Teil AD).
@@ -0,0 +1,64 @@
# Repo-Typen — Setup-Matrix (Code / Doku / Architektur / Konzept)
Die **Basis-Compliance** gilt laut DB-Vorgabe für **alle** Repo-Typen. Pipeline-/
Runtime-Bausteine kommen je nach Typ hinzu. Diese Typisierung ist eine Empfehlung;
die DB-Doku kennt formal nur „Code-Repos" (mit Pipeline) und „Doku-/Pages-Repos".
## Pflicht-Basis für JEDES Repo
Prüft die Compliance Suite unabhängig vom Typ:
- `scm-info.yaml` (`.yaml`, schema-valide) → Template `init-app-general`
- `README.md`, `LICENSE`
- Protected default branch (repräsentiert prod)
- Korrekte Sichtbarkeit (visibility) gemäß Schutzbedarf
- Secret-Scan (Betterleaks) — keine Klartext-Secrets
- Dependency-/Lizenz-Scan (Syft+Grype / Grant), SBOM
## Vergleichsmatrix
| Baustein | Code | Doku | Architektur | Konzept |
|----------|:---:|:---:|:---:|:---:|
| scm-info / README / LICENSE | ✅ | ✅ | ✅ | ✅ |
| Protected branch + tags (`*.*`) | ✅ | ✅ (branch) | ✅ (branch) | ✅ (branch) |
| Compliance-Suite-Scans | ✅ | ✅ | ✅ | ✅ |
| pipeship-Pipeline | ✅ `deploy_k8s_generic`/`release_oci_image` | ✅ `deploy_pages_generic` | /✅ wenn publiziert | |
| CDaaS Runner | ✅ eigener/Base | ✅ `cdaas-shared-agent` | ✅ shared | |
| Kubernetes-Namespace (DBCS) | ✅ | | | |
| Container-Build + Trivy/AquaSec | ✅ | | | |
| CI/CD-Secrets (age/SOPS/KMS) | ✅ falls nötig | | | |
| Container-Annotations + read-only ctx | ✅ | | | |
| SonarQube (optional) | ✅ | | | |
| Renovate | ✅ | ✅ | ✅ | |
| Linkchecker | | ✅ | ✅ | |
Legende: ✅ empfohlen/nötig · i. d. R. nicht nötig
## Pro Typ konkret
### Code-Repo (Anwendung/Service)
Vollständige CI/CD bis Prod, K8s, Container-Security. → vollständige Anleitung im POWER.md
(`deploy_k8s_generic`, K8s-Namespace, CI/CD-Secrets, Trivy, Annotations, Renovate, optional SonarQube).
### Doku-Repo (docs-as-code)
Markdown/Static-Site auf GitLab Pages: Produkt **`deploy_pages_generic`** mit eigenem
`build_website`-Job (Hugo/MkDocs/Docusaurus), Tag `cdaas-shared-agent`, **Linkchecker** inklusive,
Renovate. **Kein** K8s/Container/Trivy/Secrets.
```yaml
build_website:
image: docker-hub-remote.bahnhub.tech.rz.db.de/monachus/hugo@sha256:...
variables:
HUGO_BASEURL: "${BW_ENV_URL}"
script:
- hugo # Output muss unter ${BW_OUTPUT_DIR} (Default public) liegen
```
### Architektur-Repo (ADRs, arc42, C4, Diagrams-as-Code)
Basis-Compliance + Inhalte (Markdown/PlantUML/Mermaid/Structurizr). Wenn publiziert → wie Doku-Repo
via `deploy_pages_generic`. Sonst reicht Basis-Compliance + Markdown-Lint. Kein Container/K8s/Trivy.
### Konzept-Repo (Fachkonzepte, Specs)
Nur Basis-Compliance (meist alles). Optional `deploy_pages_generic`. `confidentiality` in scm-info
ggf. höher setzen und Repo-Sichtbarkeit anpassen (Konzepte oft vertraulicher).
## Minimaler Init-Vergleich
- **Doku/Architektur (publiziert):** Basis-Compliance + `.gitlab-ci.yml` mit `deploy_pages_generic` + Renovate. Kein K8s/Secrets/Trivy.
- **Konzept (nicht publiziert):** nur Basis-Compliance. Optional `deploy_pages_generic`.
@@ -0,0 +1,106 @@
---
name: "db-scm-info-compliance"
displayName: "DB scm-info and Compliance"
description: "Erstellt und validiert die scm-info.yaml für DB-GitLab-Repos und erklärt die Checks der DXP Compliance Suite (Secrets, Dependencies, Lizenzen, DB Compliance). Liefert eine Compliance-Checkliste, damit ein Repo konform zur DB-Vorgabe Source-Control-Management ist."
keywords: ["scm-info.yaml", "compliance suite", "betterleaks", "beam id", "dbisl lizenz", "sbom", "syft grype", "source control management", "vmp export"]
author: "einfachbahn-lab"
---
# DB scm-info and Compliance
## Overview
Diese Power hilft, ein DB-GitLab-Repo **compliant** zu machen: die Pflichtdatei
`scm-info.yaml` korrekt zu erstellen/validieren und die Checks der **DXP Compliance Suite**
(Secrets, Dependencies, Lizenzen, DB Compliance) zu verstehen und zu bestehen. Grundlage ist
die DB-Vorgabe „Source-Control- und Software-Repositories".
## scm-info.yaml — harte Regeln
- **Dateiendung muss `.yaml` sein** — `.yml` wird **nicht** akzeptiert.
- Liegt im **Repo-Root**.
- Wird gegen das **scm-info JSON Schema** validiert (`git.tech.rz.db.de/db-inner-source/scm-info-json-schema`).
- Am einfachsten per Developer-Portal-Template **`init-app-general`** erzeugen (legt scm-info.yaml + README + LICENSE an).
## Vorlagen
### Minimal
```yaml
version: v3
license: LicenseRef-DBISL
contacts: DEINE_EMAIL_ADRESSE
confidentiality: internal
reference-ids: none
```
### Erweitert (pipeship-Kontext)
```yaml
---
version: v3
license: DBISL
contacts: team@deutschebahn.com
confidentiality: internal
reference-ids: A-123456 # eure echte Beam-ID
custom:
production-branch: main
integrity: normal
availability: normal
confidentiality: normal
it-service-id: itaps-service-id-1
```
## Felder
| Feld | Zweck |
|------|-------|
| `version` | Schema-Version (z. B. `v3`) |
| `license` | Lizenz (`DBISL`/`LicenseRef-DBISL`), geprüft gegen Open-Source-Lizenzkompass |
| `contacts` | Kontakt(e) — von pipeship als Container-Annotation `GA_CONTACT` genutzt |
| `confidentiality` | Vertraulichkeitsstufe (z. B. `internal`) |
| `reference-ids` | **Beam-/Referenz-ID** (Pflicht) — pipeship-Annotation `GA_REFERENCE_ID` |
| `custom.production-branch` | Produktions-Branch (z. B. `main`) |
| `custom.integrity/availability/confidentiality` | Schutzbedarf |
| `custom.it-service-id` | ITAPS-Service-ID |
## Warum sie wichtig ist
- Verknüpfung mit **Beam/LeanIX** (Anwendungskontext)
- Bessere Erreichbarkeit über Kontaktdaten
- **VMP-Export** von Security-Findings nur mit gültiger **Beam ID** möglich
- Compliance-Pflicht — fehlt sie, entstehen Findings
- pipeship liefert daraus automatisch die Container-Annotations
## Compliance Suite — die Scanner
| Scanner | Prüft |
|---------|-------|
| **Secrets (Betterleaks)** | Passwörter/API-Keys in Code, Job-Logs, Artefakten |
| **Dependencies (Syft + Grype)** | Syft erstellt SBOM, Grype scannt auf bekannte Schwachstellen |
| **DB Compliance** | Sichtbarkeit, protected Branches, Existenz README/LICENSE/scm-info.yaml + Schema-Validierung |
| **Licenses (Grant)** | Lizenzkonformität gemäß DB Open-Source-Lizenzkompass |
- Wöchentliche Scans (Di/Do/Sa 18:00), Dependency-Checks alle 12 h, SBOM je Scan.
- Findings im Developer Portal: https://dp.dxc.comp.db.de/compliance/repositories
- Sichtbarkeit: GitLab-Rolle ≥ `Developer`. Kein DXP Mandant nötig, nur um Findings zu sehen.
## Compliance-Checkliste (vor erstem Release)
- [ ] `scm-info.yaml` vorhanden, Endung `.yaml`, schema-valide
- [ ] `reference-ids` = echte Beam-ID gesetzt
- [ ] `license` korrekt (DBISL o. zulässige Open-Source-Lizenz)
- [ ] `contacts` gesetzt (Erreichbarkeit + Container-Annotation)
- [ ] `README.md` und `LICENSE` vorhanden
- [ ] Default-Branch protected; Sichtbarkeit gemäß Schutzbedarf
- [ ] keine Klartext-Secrets im Repo/Logs/Artefakten (Betterleaks grün)
- [ ] Dependency-/Lizenz-Findings gesichtet und behandelt
- [ ] (Container) SBOM-Job aktiv, Images aktuell gehalten (≤ 14 Tage / Renovate)
## Best Practices
- `confidentiality` und Repo-Sichtbarkeit am tatsächlichen Schutzbedarf ausrichten.
- Beam-ID früh setzen — ohne sie kein VMP-Export der Findings.
- Secrets nie im Klartext; verschlüsselt mit SOPS/age committen.
- Findings nicht ignorieren — patchen/mitigieren oder Restrisiko dokumentieren.
## Troubleshooting
- **Finding „scm-info invalid"** → Endung `.yaml`? Pflichtfelder (`version`, `reference-ids`) gesetzt? Gegen Schema prüfen.
- **VMP-Export geht nicht** → gültige Beam-ID in `reference-ids` fehlt.
- **Secret-Finding trotz Verschlüsselung** → false positive dokumentieren oder Wert wirklich entfernen/rotieren.
## Weiterführend
Repo `einfachbahn-lab/doku/deployment-doku`: `docs/09-pipeship-setup-guide.md` (Teil B) und
`docs/08-dxp-plattform.md` (Kap. 4, Compliance Suite).
@@ -0,0 +1,5 @@
version: v3
license: LicenseRef-DBISL
contacts: sebastian.reinig@deutschebahn.com
confidentiality: internal
reference-ids: none
@@ -0,0 +1,40 @@
# Skills
Dieser Ordner sammelt **Kiro Skills** des Einfachbahn-Teams.
> Was ist ein Skill? Ein Skill ist eine wiederverwendbare Anleitung/Fähigkeit, die
> Kiro bei Bedarf aktiviert, um eine bestimmte Aufgabe nach einem festen Vorgehen zu
> lösen. Skills liegen lokal unter `~/.kiro/skills/` (user-level) oder `.kiro/skills/`
> (workspace-level).
## Struktur
Lege pro Skill einen eigenen Unterordner an:
```
skills/
├── README.md # diese Datei
└── <skill-name>/
└── SKILL.md # Definition des Skills
```
## Skill hinzufügen
1. Ordner `skills/<skill-name>/` anlegen.
2. `SKILL.md` mit Beschreibung, Trigger/Keywords und Schritt-für-Schritt-Anleitung
erstellen.
3. Tabelle unten aktualisieren, committen, pushen.
## Verwenden
Skill-Datei nach `~/.kiro/skills/<skill-name>/` (user-level) oder
`.kiro/skills/<skill-name>/` (workspace-level) kopieren. Kiro aktiviert den Skill dann
über die Skill-/Kontext-Auswahl.
## Enthaltene Skills
| Skill | Zweck | Trigger |
|-------|-------|---------|
| [`pytest-hypothesis`](pytest-hypothesis/) | Python-Tests mit pytest + hypothesis (Property-Based Testing) | pytest, hypothesis, unit test, python test, fixture, parametrize |
| [`docker-build-db`](docker-build-db/) | Dockerfiles für DB-Umgebung (Artifactory-Mirror, non-root, OpenShift) | Dockerfile, Docker, Container, Image, Artifactory, bahnhub, OpenShift |
| [`scm-info-setup`](scm-info-setup/) | `scm-info.yaml` erstellen und validieren (Pflichtdatei für DB-GitLab) | scm-info, compliance, beam-id, DBISL, license |
@@ -0,0 +1,189 @@
---
name: docker-build-db
description: >
Erstellt optimierte Dockerfiles und Docker-Compose-Konfigurationen für den DB-Konzern.
Berücksichtigt DB-spezifische Anforderungen: Artifactory-Mirror statt Docker Hub,
linux/amd64 Pflicht, non-root Security Context, OpenShift-Kompatibilität.
Keywords: Dockerfile, Docker, Container, Image, docker-compose, Artifactory, bahnhub, OpenShift, non-root, multi-stage.
compatibility: >
Docker Desktop oder Podman. Zugang zu bahnhub.tech.rz.db.de (Artifactory).
Für Push: API-Key über Artifactory-Profil.
metadata:
version: "1.0.0"
author: "#Einfachbahn Lab"
---
# Docker-Images für DB-Umgebung bauen
Skill für die Erstellung von Dockerfiles und Container-Images, die im DB-Konzern
(Artifactory, OpenShift/DBCS) funktionieren.
## DB-spezifische Regeln (MUST)
1. **Immer `--platform linux/amd64`** — auch auf Apple Silicon / ARM
2. **Base-Images aus Artifactory-Mirror** — kein direkter Docker-Hub-Zugriff im Cluster
3. **Non-root** — Container laufen unter zufälliger UID (OpenShift `restricted` SCC)
4. **Keine Secrets im Image** — nur über K8s-Secrets / Env-Vars zur Laufzeit
5. **Feste Tags** — semantische Versionierung (`1.2.3`), kein `latest` für Deployments
## Ablauf
### Schritt 1: Kontext erfassen
1. **Sprache/Framework** — Python, Node.js, Java, Go, ...?
2. **Artifactory-Repo** — Name des Docker-Repos (z. B. `einfachbahnlab-docker-stage-local`)
3. **Braucht der Container Schreibzugriff?** — Falls ja: welche Pfade?
4. **Health-Check-Endpoint** — Gibt es `/health` o. ä.?
5. **Deployment-Ziel** — OpenShift (DBCS), lokal, AWS?
### Schritt 2: Dockerfile erstellen
## Dockerfile Patterns
### Python (Multi-Stage)
```dockerfile
# syntax=docker/dockerfile:1
FROM docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14-slim AS builder
WORKDIR /build
COPY pyproject.toml .
COPY src/ src/
RUN pip install --no-cache-dir --target=/install .
FROM docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14-slim
# Non-root: OpenShift vergibt zufällige UID
RUN useradd -r -u 1001 appuser
WORKDIR /app
COPY --from=builder /install /usr/local/lib/python3.14/site-packages
COPY src/ src/
# Schreibbare Verzeichnisse (falls nötig)
RUN mkdir -p /app/data && chmod 777 /app/data
USER 1001
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD python -c "import httpx; httpx.get('http://localhost:8000/health').raise_for_status()"
ENTRYPOINT ["python", "-m", "ai_orchestrator.cli"]
```
### Node.js (Multi-Stage)
```dockerfile
# syntax=docker/dockerfile:1
FROM docker-hub-remote.bahnhub.tech.rz.db.de/node:22-slim AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
FROM docker-hub-remote.bahnhub.tech.rz.db.de/node:22-slim
WORKDIR /app
COPY --from=builder /build/dist ./dist
COPY --from=builder /build/node_modules ./node_modules
COPY package.json .
USER 1001
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD node -e "fetch('http://localhost:3000/health').then(r=>{if(!r.ok)throw r})"
CMD ["node", "dist/index.js"]
```
### Go (Scratch)
```dockerfile
# syntax=docker/dockerfile:1
FROM docker-hub-remote.bahnhub.tech.rz.db.de/golang:1.24 AS builder
WORKDIR /src
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /app ./cmd/server
FROM scratch
COPY --from=builder /app /app
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
USER 65534
EXPOSE 8080
ENTRYPOINT ["/app"]
```
## docker-compose.yml (Entwicklung)
```yaml
services:
app:
build:
context: .
dockerfile: Dockerfile
platforms:
- linux/amd64
ports:
- "8000:8000"
env_file:
- .env
volumes:
- app-data:/app/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 5s
retries: 3
volumes:
app-data:
```
## Build & Push Workflow
```bash
# 1. Login ins Artifactory
docker login einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de
# User: DeBi-Kürzel, Password: API-Key aus Artifactory-Profil
# 2. Build (IMMER mit platform!)
docker build --platform linux/amd64 \
-t einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/myapp:1.0.0 .
# 3. Push
docker push einfachbahnlab-docker-stage-local.bahnhub.tech.rz.db.de/myapp:1.0.0
```
## OpenShift-Kompatibilität Checkliste
- [ ] Base-Image aus `docker-hub-remote.bahnhub.tech.rz.db.de` (Mirror)
- [ ] `USER 1001` (oder andere nicht-root UID) gesetzt
- [ ] Keine `privileged`-Operationen (kein `apt-get` zur Laufzeit)
- [ ] Schreibbare Pfade: `chmod 777` oder als Volume mounten
- [ ] `HEALTHCHECK` definiert (wird für Liveness/Readiness-Probes genutzt)
- [ ] Keine Secrets im Image — nur Env-Vars / K8s-Secrets
- [ ] Festes Tag (semantisch), kein `:latest`
- [ ] `--platform linux/amd64` beim Build
## Troubleshooting
| Problem | Ursache | Lösung |
|---------|---------|--------|
| `exec format error` | Falsches Architektur | `--platform linux/amd64` beim Build |
| `permission denied` auf Dateien | Non-root UID hat keinen Zugriff | `chmod 777` oder `chown 1001` |
| `ImagePullBackOff` | Image nicht im Cluster erreichbar | Image-Pull-Secret prüfen, Registry-URL korrekt? |
| `unauthorized` beim Push | Nicht eingeloggt oder kein Recht | `docker login` + API-Key prüfen, Repo existiert? |
| Base-Image nicht gefunden | Docker-Hub-Mirror-Pfad falsch | `docker-hub-remote.bahnhub.tech.rz.db.de/<image>` |
## Best Practices
- **Multi-Stage Builds** — Build-Dependencies nicht im finalen Image
- **`.dockerignore`** — `.git`, `__pycache__`, `node_modules`, `.env` ausschließen
- **Reproducible Builds** — Lock-Files verwenden (`pip freeze`, `npm ci`)
- **Kleine Images** — `slim` oder `alpine` Base-Images bevorzugen
- **Layer-Caching** — Dependencies vor Source-Code kopieren
- **SBOM** — Image-SBOM mit Syft generieren (pipeship macht das automatisch)
@@ -0,0 +1,236 @@
---
name: pytest-hypothesis
description: >
Erstellt und verbessert Unit Tests in Python mit pytest und hypothesis (Property-Based Testing).
Nutze diesen Skill wenn der User Tests für Python-Code schreiben, verbessern oder die
Test-Coverage erhöhen möchte. Umfasst pytest-Patterns, hypothesis-Strategien, Fixtures,
parametrisierte Tests und Coverage-Optimierung.
Keywords: pytest, hypothesis, unit test, property-based, test coverage, python test, fixture, parametrize.
compatibility: >
Python 3.12+ mit pytest (>=8.0), pytest-asyncio (>=1.0), hypothesis (>=6.100).
Optional: pytest-cov für Coverage-Reports.
metadata:
version: "1.0.0"
author: "#Einfachbahn Lab"
---
# Python Testing mit pytest + hypothesis
Skill für qualitativ hochwertige Python-Tests: klassische Unit Tests mit pytest und
Property-Based Tests mit hypothesis.
## Grundprinzipien
- **pytest** für determinstische Tests mit konkreten Ein-/Ausgaben
- **hypothesis** für Property-Based Tests: automatisch generierte Eingaben prüfen Invarianten
- Beide ergänzen sich: pytest für bekannte Szenarien, hypothesis für unerwartete Edge Cases
## Ablauf
### Schritt 1: Kontext erfassen
1. **Zu testende Komponente** — Welche Datei/Klasse/Funktion?
2. **Vorhandene Tests?** — Gibt es bereits Tests, die ergänzt werden sollen?
3. **Async?** — Nutzt der Code `async/await`?
4. **Externe Abhängigkeiten?** — Welche müssen gemockt werden?
### Schritt 2: Test-Typ wählen
| Situation | Test-Typ |
|-----------|----------|
| Konkrete Ein-/Ausgabe bekannt | pytest (klassisch) |
| Invariante/Eigenschaft prüfbar | hypothesis (property-based) |
| Async I/O | pytest-asyncio |
| Mehrere ähnliche Fälle | `@pytest.mark.parametrize` |
| Komplexes Setup | Fixtures (`@pytest.fixture`) |
### Schritt 3: Tests implementieren
## Conventions
### Dateistruktur
```
tests/
├── __init__.py
├── test_<modul>.py # Klassische Tests
├── test_<modul>_properties.py # Property-Based Tests (Suffix!)
└── conftest.py # Shared Fixtures
```
### Namenskonvention
```python
# Klassischer Test
def test_<funktion>_<szenario>_<erwartung>():
...
# Property-Based Test
@given(...)
def test_<funktion>_<eigenschaft>(value):
...
```
## pytest Patterns
### AAA-Pattern (Arrange-Act-Assert)
```python
def test_calculate_total_with_valid_items_returns_sum():
# Arrange
items = [Item(price=10.0), Item(price=20.0)]
calculator = PriceCalculator()
# Act
result = calculator.total(items)
# Assert
assert result == 30.0
```
### Parametrize
```python
@pytest.mark.parametrize("input_val,expected", [
("valid@email.de", True),
("invalid", False),
("", False),
("a@b.c", True),
])
def test_validate_email(input_val, expected):
assert validate_email(input_val) == expected
```
### Fixtures
```python
@pytest.fixture
def sample_config():
"""Liefert eine Test-Konfiguration."""
return Config(
endpoint="https://test.example.com",
api_key="test-key-123",
timeout_ms=5000,
)
def test_client_uses_config_endpoint(sample_config):
client = Client(sample_config)
assert client.base_url == "https://test.example.com"
```
### Async Tests
```python
import pytest
@pytest.mark.asyncio
async def test_fetch_data_returns_items():
client = AsyncClient(base_url="https://test.example.com")
result = await client.fetch_items()
assert len(result) > 0
```
### Mocking
```python
from unittest.mock import AsyncMock, patch
@pytest.mark.asyncio
async def test_orchestrator_dispatches_task():
mock_tracker = AsyncMock()
mock_tracker.get_ready_tasks.return_value = [task]
orchestrator = Orchestrator(tracker=mock_tracker)
await orchestrator.poll()
mock_tracker.move_task.assert_called_once_with(task.id, "in_progress")
```
## hypothesis Patterns
### Einfache Strategien
```python
from hypothesis import given, settings, assume
from hypothesis import strategies as st
@given(st.integers(), st.integers())
def test_addition_is_commutative(a, b):
assert add(a, b) == add(b, a)
@given(st.text(min_size=1))
def test_parse_never_crashes(text):
# Darf Exception werfen, aber nie crashen
try:
parse(text)
except ValidationError:
pass # Erwartetes Verhalten
```
### Composite Strategien (eigene Datentypen)
```python
@st.composite
def config_strategy(draw):
"""Generiert zufällige aber valide Config-Objekte."""
return Config(
endpoint=draw(st.from_regex(r"https://[a-z]+\.example\.com", fullmatch=True)),
api_key=draw(st.text(min_size=8, max_size=64, alphabet=st.characters(whitelist_categories=("L", "N")))),
timeout_ms=draw(st.integers(min_value=100, max_value=30000)),
)
@given(config_strategy())
def test_config_serialization_roundtrip(config):
serialized = config.to_dict()
restored = Config.from_dict(serialized)
assert restored == config
```
### Settings anpassen
```python
from hypothesis import settings, Phase
@settings(
max_examples=200, # Mehr Beispiele für kritische Funktionen
deadline=None, # Kein Timeout für langsame Tests
)
@given(st.lists(st.integers()))
def test_sort_produces_sorted_output(lst):
result = custom_sort(lst)
assert all(result[i] <= result[i+1] for i in range(len(result) - 1))
```
### Typische Properties (Invarianten)
| Property | Beispiel |
|----------|----------|
| Roundtrip | `deserialize(serialize(x)) == x` |
| Idempotenz | `f(f(x)) == f(x)` |
| Kommutativität | `f(a, b) == f(b, a)` |
| Monotonie | `a <= b → f(a) <= f(b)` |
| Invariante | `len(filter(lst)) <= len(lst)` |
| Keine Crashes | `f(random_input)` wirft keinen unerwarteten Error |
## Coverage
### Coverage messen
```bash
pytest --cov=src --cov-report=html --cov-report=term-missing
```
### Ziele
- **Gesamtprojekt:** ≥ 80% Line Coverage
- **Domain-Logik:** ≥ 90% Branch Coverage
- **Integrationspunkte:** Property-Based Tests für Serialisierung/Parsing
## Checkliste
- [ ] Alle öffentlichen Funktionen/Methoden haben mindestens einen Test
- [ ] Positive und negative Szenarien abgedeckt
- [ ] Edge Cases: leere Listen, None, Grenzwerte
- [ ] Property-Based Tests für Serialisierung/Roundtrips
- [ ] Async-Code mit `@pytest.mark.asyncio` getestet
- [ ] Externe Abhängigkeiten gemockt (kein Netzwerk/DB in Unit Tests)
- [ ] Testnamen beschreiben das erwartete Verhalten
- [ ] Coverage ≥ 80%
## Troubleshooting
| Problem | Lösung |
|---------|--------|
| `hypothesis.errors.DeadlineExceeded` | `@settings(deadline=None)` oder Code beschleunigen |
| `hypothesis.errors.Flaky` | Test ist nicht deterministisch → externe Abhängigkeit mocken |
| `pytest.mark.asyncio` nicht erkannt | `pytest-asyncio` installieren, `asyncio_mode = "auto"` in pyproject.toml |
| Fixtures nicht gefunden | In `conftest.py` verschieben (gleiche oder übergeordnete Ebene) |
| Coverage zu niedrig | Branch-Report prüfen: `--cov-branch`, fehlende Error-Pfade testen |
@@ -0,0 +1,117 @@
---
name: scm-info-setup
description: >
Erstellt und validiert die scm-info.yaml für DB-GitLab-Repos.
Stellt sicher, dass die Datei schema-konform ist und alle Pflichtfelder
(version, license, contacts, confidentiality, reference-ids) korrekt gesetzt sind.
Keywords: scm-info, scm-info.yaml, compliance, beam-id, DBISL, license, reference-ids.
compatibility: >
Jedes Projekt im DB-GitLab (git.tech.rz.db.de). Keine speziellen Tools nötig.
metadata:
version: "1.0.0"
author: "#Einfachbahn Lab"
---
# scm-info.yaml erstellen und validieren
Skill für die korrekte Erstellung der Pflichtdatei `scm-info.yaml` in DB-GitLab-Repos.
## Warum?
Die `scm-info.yaml` ist **Pflicht** für jedes Repo im DB-GitLab:
- Verknüpft das Repo mit Beam/LeanIX (Anwendungskontext)
- Ermöglicht VMP-Export von Security-Findings (nur mit gültiger Beam-ID)
- Liefert Kontaktdaten für automatische Container-Annotations
- Wird von der DXP Compliance Suite geprüft — fehlt sie, entstehen Findings
## Harte Regeln (MUST)
1. **Dateiendung `.yaml`**`.yml` wird NICHT akzeptiert
2. **Liegt im Repo-Root** — nicht in Unterordnern
3. **Schema-valide** — wird gegen das scm-info JSON Schema geprüft
4. **`reference-ids` muss gesetzt sein** — echte Beam-ID oder `none`
## Ablauf
### Schritt 1: Informationen ermitteln
1. **Beam-/Referenz-ID** — Aus LeanIX/Beam ermitteln (Format: `A-123456`). Falls unbekannt: `none`
2. **Kontakt-E-Mail** — Team oder Person (wird Container-Annotation `GA_CONTACT`)
3. **Lizenz** — Fast immer `LicenseRef-DBISL` (DB-intern). Open Source: passende Lizenz
4. **Vertraulichkeitsstufe**`internal` (Standard), `public`, `confidential`
### Schritt 2: Datei erstellen
### Minimal-Template
```yaml
---
version: v3
license: LicenseRef-DBISL
contacts: team@deutschebahn.com
confidentiality: internal
reference-ids: none
```
### Erweitert (mit Beam-ID und Custom-Feldern)
```yaml
---
version: v3
license: LicenseRef-DBISL
contacts: team@deutschebahn.com
confidentiality: internal
reference-ids: A-123456
custom:
production-branch: main
integrity: normal
availability: normal
confidentiality: normal
it-service-id: itaps-service-id-1
```
### Schritt 3: Validierung
Prüfe nach Erstellung:
- [ ] Datei heißt `scm-info.yaml` (nicht `.yml`!)
- [ ] Liegt im Repo-Root
- [ ] `version: v3` gesetzt
- [ ] `license` ist gültig (`LicenseRef-DBISL` oder Open-Source-Lizenz)
- [ ] `contacts` enthält gültige E-Mail-Adresse
- [ ] `confidentiality` ist einer von: `public`, `internal`, `confidential`
- [ ] `reference-ids` gesetzt (Beam-ID oder `none`)
## Felder-Referenz
| Feld | Pflicht | Werte | Hinweis |
|------|---------|-------|---------|
| `version` | ✅ | `v3` | Schema-Version |
| `license` | ✅ | `LicenseRef-DBISL`, `Apache-2.0`, `MIT`, ... | Lizenzkompass beachten |
| `contacts` | ✅ | E-Mail-Adresse(n) | Wird Container-Annotation |
| `confidentiality` | ✅ | `public`, `internal`, `confidential` | Repo-Sichtbarkeit anpassen |
| `reference-ids` | ✅ | Beam-ID (`A-123456`) oder `none` | Ohne ID kein VMP-Export |
| `custom.production-branch` | ❌ | Branch-Name | Für pipeship |
| `custom.integrity` | ❌ | `normal`, `high`, `very_high` | Schutzbedarf |
| `custom.availability` | ❌ | `normal`, `high`, `very_high` | Schutzbedarf |
| `custom.it-service-id` | ❌ | ITAPS-ID | Service-Zuordnung |
## Häufige Fehler
| Fehler | Finding | Lösung |
|--------|---------|--------|
| Datei heißt `scm-info.yml` | „scm-info invalid" | Umbenennen zu `.yaml` |
| `reference-ids` fehlt | „scm-info invalid" | Feld ergänzen (auch `none` ist valide) |
| Keine `contacts` | Schema-Fehler | Gültige E-Mail eintragen |
| YAML-Syntaxfehler | „scm-info invalid" | YAML-Linting prüfen |
| VMP-Export geht nicht | — | Echte Beam-ID statt `none` eintragen |
## Zusammenspiel mit pipeship
Wenn pipeship aktiv ist, werden aus `scm-info.yaml` automatisch:
- **`GA_REFERENCE_ID`** ← `reference-ids` (Container-Annotation)
- **`GA_CONTACT`** ← `contacts` (Container-Annotation)
- Compliance Suite prüft zusätzlich: Protected Branches, README, LICENSE
## Weiterführend
- Schema: `git.tech.rz.db.de/db-inner-source/scm-info-json-schema`
- Schnellstart: Developer-Portal-Template `init-app-general` (legt scm-info + README + LICENSE an)
- Compliance-Findings: https://dp.dxc.comp.db.de/compliance/repositories
@@ -0,0 +1,53 @@
# Steerings
Dieser Ordner sammelt **Kiro Steering-Dateien** des Einfachbahn-Teams.
> Was ist Steering? Steering-Dateien liefern zusätzlichen Kontext und Anweisungen, die
> Kiro bei allen oder bestimmten Interaktionen berücksichtigt — z. B. Team-Standards,
> Projektwissen oder How-tos (Build/Test/Deploy). Sie liegen im Workspace unter
> `.kiro/steering/*.md`.
## Inclusion-Modi
Über das Frontmatter steuerbar:
- **Always** (Default): immer aktiv.
- **fileMatch**: nur wenn eine passende Datei in den Kontext geladen wird.
```
---
inclusion: fileMatch
fileMatchPattern: 'README*'
---
```
- **manual**: nur wenn per `#` im Chat referenziert.
```
---
inclusion: manual
---
```
Steering-Dateien können weitere Dateien referenzieren via
`#[[file:<relativer_pfad>]]` (z. B. OpenAPI-/GraphQL-Specs).
## Struktur
```
steerings/
├── README.md # diese Datei
└── <thema>.md # einzelne Steering-Datei
```
## Steering hinzufügen
1. `steerings/<thema>.md` anlegen (optional mit Frontmatter für den Inclusion-Modus).
2. Tabelle unten aktualisieren, committen, pushen.
## Verwenden
Datei nach `.kiro/steering/` im Ziel-Workspace kopieren.
## Enthaltene Steerings
| Datei | Zweck | Inclusion |
|-------|-------|-----------|
| [`einfachbahn-naming.md`](einfachbahn-naming.md) | Schreibweise des Teamnamens immer als `#Einfachbahn` | always |
@@ -0,0 +1,23 @@
---
inclusion: always
---
# Schreibweise: #Einfachbahn
Der Teamname wird **immer** mit vorangestelltem Hashtag und großem „E" geschrieben:
> **#Einfachbahn**
## Regeln
- Korrekt: `#Einfachbahn`
- Falsch: `einfachbahn`, `Einfachbahn`, `EinfachBahn`, `#einfachbahn`, `# Einfachbahn` (Leerzeichen nach `#`)
- Der Hashtag gehört direkt an das Wort, ohne Leerzeichen: `#Einfachbahn`.
- Gilt in Prosa, Dokumentation, Commit-Messages, READMEs und UI-Texten.
## Ausnahmen
- In technischen Bezeichnern (URLs, Repo-/Pfadnamen, Slugs, Code-Identifier) bleibt die
jeweils dort gültige Schreibweise erhalten, z. B. `einfachbahn-lab` in GitLab-Pfaden.
- In Markdown-Überschriften das `#` der Überschrift nicht mit dem Marken-Hashtag
verwechseln — die Marke schreibt sich dort `# #Einfachbahn ...`.