From 97fe5cb22af4e4e53d802d1d0acfb2a63105e3b7 Mon Sep 17 00:00:00 2001 From: m3ta-chiron Date: Sat, 22 Aug 2026 10:03:29 +0200 Subject: [PATCH] feat: scaffold content repo with guard rules per artifact type - add skills/, commands/, agents/, mcp/ artifact directories - document contribution guard rules per artifact type (spec B1) - document content/mechanism split with az-fleet and ref pinning - document tests/fixtures/ convention (never delivered) Closes az-agent-defaults-j35 --- .beads/interactions.jsonl | 1 + .beads/issues.jsonl | 5 + README.md | 255 ++++++++++++++++++++++++++++++++++++++ agents/.gitkeep | 0 commands/.gitkeep | 0 mcp/.gitkeep | 0 skills/.gitkeep | 0 tests/fixtures/.gitkeep | 0 8 files changed, 261 insertions(+) create mode 100644 .beads/issues.jsonl create mode 100644 README.md create mode 100644 agents/.gitkeep create mode 100644 commands/.gitkeep create mode 100644 mcp/.gitkeep create mode 100644 skills/.gitkeep create mode 100644 tests/fixtures/.gitkeep diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index e69de29..0722b84 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -0,0 +1 @@ +{"id":"int-97b8d2f545bb01e5a71868be1b46d3e6","kind":"field_change","created_at":"2026-08-22T08:02:44.467228132Z","actor":"m3tam3re","issue_id":"az-agent-defaults-j35","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Closed"}} diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl new file mode 100644 index 0000000..bfdf8d6 --- /dev/null +++ b/.beads/issues.jsonl @@ -0,0 +1,5 @@ +{"_type":"issue","id":"az-agent-defaults-j35","title":"Repo-Gerüst: vier Artefakt-Verzeichnisse + README mit Guard-Regeln je Artefakt-Typ","description":"Quelle: Spec 01-az-agent-defaults-spec.md (lokal, wird nicht gepusht).\n\naz-agent-defaults wird als reines Content-Repo die eine Wahrheitsquelle für das Company-Default-Set. Dieses Ticket liefert das Gerüst: die vier Artefakt-Verzeichnisse (skills/, commands/, agents/, mcp/) und ein README, das die Contribution-Guard-Regeln je Artefakt-Typ so dokumentiert, dass ein Fachbereichs-Contributor ohne Architektur-Wissen richtig beisteuern kann:\n\n- Skills: Ordner mit SKILL.md und Frontmatter-Öffner (wie heute)\n- Commands: Markdown mit Frontmatter (description, optional agent/model) und Template-Body (Argument-Platzhalter erlaubt)\n- Agents: Markdown mit Frontmatter (description, mode primary/subagent, optional model/temperature, Permission-Profil); Subagent-Definitionen müssen über das Task-Tool aufrufbar bleiben\n- MCP: Fragmente für den mcp-Konfigurationsschlüssel, remote/streamable als Standard, Secrets grundsätzlich nur als Platzhalter\n\nDas README hält außerdem fest: Auslieferung und Guard-Engine (Pre-Flight auf dem Controller) leben im Fleet-Repo az-fleet; dieses Repo ist Content-only und über den Repo-Ref pinbar (Default: main). Zudem die Fixtures-Konvention: Testgegenstände für die Guard-Tests leben unter tests/fixtures/ und werden nie ausgeliefert, weil die Delivery-Rolle nur die vier Typ-Verzeichnisse liest (Sonntags-Entscheidung). Das Repo verabschiedet damit den Namen az-agent-skills (User Story 2).","acceptance_criteria":"- Die vier Artefakt-Verzeichnisse skills/, commands/, agents/, mcp/ sind im Repo angelegt\n- README dokumentiert die Guard-Regeln je Artefakt-Typ vollständig (Struktur-/Frontmatter-/Platzhalter-Anforderungen gemäß Spec B1)\n- README erklärt die Content/Mechanismus-Trennung zu az-fleet (Guard-Engine und Auslieferung dort) und das Ref-Pinning\n- Die Fixtures-Konvention tests/fixtures/ ist dokumentiert (nie ausgeliefert; Begründung: Delivery liest nur die vier Typ-Verzeichnisse)\n- Ein Contributor ohne Architektur-Wissen kann anhand des README allein entscheiden, wohin ein neues Artefakt gehört und ob es die Guard-Regeln erfüllt","status":"closed","priority":1,"issue_type":"task","assignee":"m3tam3re","owner":"p@m3ta.dev","created_at":"2026-08-22T07:57:14Z","created_by":"m3tam3re","updated_at":"2026-08-22T08:02:44Z","started_at":"2026-08-22T07:59:36Z","closed_at":"2026-08-22T08:02:44Z","close_reason":"Closed","labels":["ready-for-agent"],"dependency_count":0,"dependent_count":4,"comment_count":0} +{"_type":"issue","id":"az-agent-defaults-95y","title":"MCP-Slice: Fragment-Format (remote/streamable) + Vault-Platzhalter-Konvention + Guard-Fixtures","description":"Quelle: Spec 01-az-agent-defaults-spec.md.\n\nDefinition des MCP-Fragment-Formats für den mcp-Konfigurationsschlüssel: ein Fragment pro Server, remote/streamable als Standard (url, enabled-Flag; OAuth läuft zur Laufzeit pro Nutzer über das Microsoft-Konto — keine statischen Secrets im Fragment). Für Ausnahmen mit statischem Key definiert das Format einen Platzhalter samt Vault-Key-Namensschema: der Key liegt im Vault des Fleet-Repos und wird erst beim Merge auf dem Controller substituiert — im Repo bleibt nie ein Secret (B3).\n\nZwei Referenz-Fragmente in mcp/ (eine OAuth-Server-Anbindung, eine Key-Ausnahme mit Platzhalter) dienen als Testgegenstände für die Fleet-Szenarien „Fragmente in der aufgelösten Konfiguration sichtbar (Sidecar-Debug)\" und „Vault-Substitution funktioniert, Nutzerebene enthält kein Secret aus dem Repo\". Zusätzlich ungültige MCP-Fixtures unter tests/fixtures/ — insbesondere ein Fragment mit Inline-Secret, das der Guard rot abbrechen muss.\n","acceptance_criteria":"- Das Fragment-Format ist im README dokumentiert (ein Fragment pro Server; Felder für remote/streamable; enabled-Flag)\n- Die Platzhalter-Konvention für Key-Ausnahmen ist definiert (Syntax + Vault-Key-Namensschema; Substitution nur beim Merge auf dem Controller)\n- Ein OAuth-Referenz-Fragment und ein Key-Ausnahme-Referenz-Fragment liegen in mcp/ — beide ohne jedes Secret\n- Ungültige MCP-Testgegenstände existieren unter tests/fixtures/ (mindestens: Fragment mit Inline-Secret)\n- Keine Fixture liegt in einem ausgelieferten Typ-Verzeichnis","status":"open","priority":2,"issue_type":"feature","owner":"p@m3ta.dev","created_at":"2026-08-22T07:57:49Z","created_by":"m3tam3re","updated_at":"2026-08-22T07:57:49Z","labels":["ready-for-agent"],"dependencies":[{"issue_id":"az-agent-defaults-95y","depends_on_id":"az-agent-defaults-j35","type":"blocks","created_at":"2026-08-22T09:57:48Z","created_by":"m3tam3re","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"az-agent-defaults-gj1","title":"Commands-Slice: Referenz-Command mit Argument-Platzhaltern + Guard-Fixtures","description":"Quelle: Spec 01-az-agent-defaults-spec.md.\n\nErster exemplarischer Company-Command in commands/: Markdown mit Frontmatter (description, optional agent/model) und Template-Body mit Argument-Platzhaltern ($ARGUMENTS, $1..$n) — Format gemäß verifizierter OpenCode-Doku (global ~/.config/opencode/commands/, pro Projekt .opencode/commands/; Shell-Output-Injection und Datei-Referenzen unterstützt). Der Command ist zugleich Referenz-Beitrag für Contributor und Testgegenstand für das Fleet-Szenario „/command ist in der OpenWork-/OpenCode-Sitzung verfügbar und löst das Template aus\". Inhaltlich bewusst trivial (Platzhalter-Niveau wie ow-hello; konkrete Inhalte sind Phase 2).\n\nZusätzlich ungültige Command-Fixtures unter tests/fixtures/ (z. B. Frontmatter ohne description, Datei ohne Frontmatter).\n","acceptance_criteria":"- Ein gültiger Referenz-Command liegt in commands/ und erfüllt die README-Guard-Regeln (description im Frontmatter, Template-Body, Argument-Platzhalter genutzt)\n- Der Command folgt dem OpenCode-Command-Format, sodass er nach Fleet-Auslieferung als /slash-Befehl verfügbar ist und das Template auslöst\n- Ungültige Command-Testgegenstände existieren unter tests/fixtures/ (mindestens: ohne description, ohne Frontmatter)\n- Keine Fixture liegt in einem ausgelieferten Typ-Verzeichnis","status":"open","priority":2,"issue_type":"feature","owner":"p@m3ta.dev","created_at":"2026-08-22T07:57:49Z","created_by":"m3tam3re","updated_at":"2026-08-22T07:57:49Z","labels":["ready-for-agent"],"dependencies":[{"issue_id":"az-agent-defaults-gj1","depends_on_id":"az-agent-defaults-j35","type":"blocks","created_at":"2026-08-22T09:57:48Z","created_by":"m3tam3re","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"az-agent-defaults-gyj","title":"Agents-Slice: Referenz-Primäragent + Read-only-Subagent + Guard-Fixtures","description":"Quelle: Spec 01-az-agent-defaults-spec.md.\n\nZwei Referenz-Agent-Definitionen in agents/: ein spezialisierter Primäragent (per Agentenwechsel erreichbar) und ein Subagent mit Read-only-Permission-Profil (kein Edit/Bash) — Spezialisierung ohne Rechteausweitung (User Story 13). Beide folgen dem OpenCode-Format: Markdown mit Frontmatter (description, mode primary/subagent, optional model/temperature, Permission-Profil); Dateiname = Agentenname.\n\nKritisch: Die Subagent-Definition darf die Task-Tool-Delegation nie verbauen — Agenten müssen Subagenten weiterhin selbstständig starten können (User Story 12), und Permission-Profile dürfen niemals etwas erlauben, was der Managed-Layer verweigert (User Story 14).\n\nZusätzlich ungültige Agent-Fixtures unter tests/fixtures/ (z. B. mode fehlt, description fehlt).\n","acceptance_criteria":"- Ein Primäragent (mode: primary) und ein Subagent (mode: subagent) liegen in agents/ und erfüllen die README-Guard-Regeln\n- Der Subagent trägt ein Read-only-Permission-Profil ohne Edit/Bash\n- Die Subagent-Definition lässt Task-Tool-Aufruf und @mention zu (verbaut die Delegationsfähigkeit nicht)\n- Keine Agent-Definition weicht die Sicherheitsgrenzen des Managed-Layers auf (bleibt innerhalb des Permission-Regelwerks)\n- Ungültige Agent-Testgegenstände existieren unter tests/fixtures/ (mindestens: mode fehlt, description fehlt)\n- Keine Fixture liegt in einem ausgelieferten Typ-Verzeichnis","status":"open","priority":2,"issue_type":"feature","owner":"p@m3ta.dev","created_at":"2026-08-22T07:57:49Z","created_by":"m3tam3re","updated_at":"2026-08-22T07:57:49Z","labels":["ready-for-agent"],"dependencies":[{"issue_id":"az-agent-defaults-gyj","depends_on_id":"az-agent-defaults-j35","type":"blocks","created_at":"2026-08-22T09:57:48Z","created_by":"m3tam3re","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} +{"_type":"issue","id":"az-agent-defaults-dzx","title":"Skills-Slice: ow-hello aus az-agent-skills übernehmen + Skill-Guard-Fixtures","description":"Quelle: Spec 01-az-agent-defaults-spec.md.\n\nDer Pilot-Skill ow-hello wandert aus dem Vorgänger-Repo az-agent-skills in skills/ — inhaltlich unverändert; einzig die Erwähnung „Repository az-agent-skills\" im Skill-Text wird auf az-agent-defaults aktualisiert (Ticketing-Entscheidung 22.08.2026). Damit bleibt der bestehende Skills-Spiegel (ADR-0006-Logik) ohne Funktionsverlust funktionsfähig.\n\nZusätzlich entstehen die Testgegenstände für den Guard-Test „ungültiges Artefakt im Repo → Run bricht kontrolliert ab\": unter tests/fixtures/ ungültige Skill-Artefakte (z. B. Ordner ohne SKILL.md; SKILL.md ohne Frontmatter-Öffner). Die Guard-Engine selbst implementiert az-fleet (Pre-Flight der Delivery-Rolle).\n","acceptance_criteria":"- ow-hello liegt in skills/ und ist inhaltlich identisch mit dem Stand aus az-agent-skills (einzige Abweichung: Repo-Erwähnung az-agent-defaults)\n- Frontmatter-Öffner und Struktur erfüllen die im README dokumentierten Skill-Guard-Regeln\n- Unter tests/fixtures/ existieren ungültige Skill-Testgegenstände (mindestens: Ordner ohne SKILL.md, SKILL.md ohne Frontmatter-Öffner)\n- Keine Fixture liegt in einem der vier ausgelieferten Typ-Verzeichnisse","status":"open","priority":2,"issue_type":"feature","owner":"p@m3ta.dev","created_at":"2026-08-22T07:57:48Z","created_by":"m3tam3re","updated_at":"2026-08-22T07:57:48Z","labels":["ready-for-agent"],"dependencies":[{"issue_id":"az-agent-defaults-dzx","depends_on_id":"az-agent-defaults-j35","type":"blocks","created_at":"2026-08-22T09:57:48Z","created_by":"m3tam3re","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0} diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a6b2a6 --- /dev/null +++ b/README.md @@ -0,0 +1,255 @@ +# az-agent-defaults — Company-Default-Set für Agenten-Artefakte + +Dieses Repo ist die **eine Wahrheitsquelle** für die Standard-Artefakte, die jede +Agenten-Workstation der AZ-Gruppe gespiegelt bekommt. Es ist ein **reines +Content-Repo**: hier leben nur die Inhalte — die Technik, die sie ausliefert und +absichert, gehört in das Fleet-Repo `az-fleet` (siehe [Trennung Content / +Mechanismus](#trennung-content--mechanismus)). + +Das Repo hervorgegangen aus `az-agent-skills` und löst es ab: der alte Name +würde lügen, seit neben Skills auch Commands, Agenten-Definitionen und +MCP-Server-Anbindungen dazugekommen sind. + +--- + +## Wohin gehört mein Beitrag? + +| Ich möchte beitragen … | Verzeichnis | Form | +|---|---|---| +| einen Skill (Verhaltens-Anweisung, die der Agent bei Bedarf lädt) | `skills//` | Ordner mit `SKILL.md` | +| einen Command (/slash-Befehl, wiederverwendbarer Prompt) | `commands/.md` | Markdown-Datei mit Frontmatter | +| einen Agenten (spezialisiertes Profil als Primäragent oder Subagent) | `agents/.md` | Markdown-Datei mit Frontmatter | +| einen MCP-Server (Werkzeug-Anbindung) | `mcp/.yaml` | Konfigurations-Fragment | + +Kurzform zum Einsortieren: + +- **Verhalten beibringen** („mach X, wenn Y") → `skills/` +- **Wiederkehrenden Prompt als Tastendruck** → `commands/` +- **Eigenes Agenten-Profil / Prüf-Subagenten** → `agents/` +- **Werkzeug anbinden** (API, Datenquelle) → `mcp/` + +Alle vier Verzeichnisse werden von der Delivery-Rolle des Fleet-Repos gelesen +— und **nur** diese vier. Alles andere im Repo (z. B. `tests/fixtures/`, diese +README, die Spec) wird nie ausgeliefert. + +--- + +## Guard-Regeln je Artefakt-Typ + +Die Delivery-Rolle in `az-fleet` führt vor jedem Rollout einen **deterministischen +Pre-Flight-Guard** aus: Struktur-, Frontmatter- und Platzhalter-Checks je Typ. +Ein ungültiges Artefakt **bricht den Run kontrolliert ab** — kaputte Inhalte +erreichen nie eine Maschine. Die Regeln unten beschreiben, was der Guard +mindestens prüft; die Implementierung lebt in `az-fleet`, nicht hier. + +### `skills/` — Skills + +**Struktur:** ein Ordner pro Skill, darin genau eine `SKILL.md`. + +``` +skills/ +└── mein-skill/ + └── SKILL.md +``` + +**Anforderungen:** + +- Ordnername = Skill-Name (kein Leerzeichen, keine Umlaute; kebab-case). +- `SKILL.md` beginnt mit einem YAML-Frontmatter-Öffner (Delimited by `---`). +- Frontmatter enthält **Pflichtfelder** `name` und `description`. + - `name` muss zum Ordnernamen passen. + - `description` ist ein Satz, der sagt, wann der Skill greift. +- Darunter: Anweisungen als normales Markdown. + +**Minimalbeispiel:** + +```markdown +--- +name: mein-skill +description: Prüft Zugferd-Rechnungen auf formal korrektes XML, wenn der Nutzer eine XRechnung validieren will. +--- + +# Zugferd-Validierung + +Prüfe die übergebene Datei gegen das CIUS-XRechnung-Schema … +``` + +**Typische Fehler, die der Guard abbricht:** fehlender Ordner, fehlende +`SKILL.md`, fehlendes/leeres Frontmatter, `name` ≠ Ordnername, fehlende +`description`. + +### `commands/` — Commands (/slash-Befehle) + +**Struktur:** eine Markdown-Datei pro Command, direkt in `commands/`. + +``` +commands/ +└── ticket-abarbeiten.md +``` + +**Anforderungen:** + +- Dateiname ohne `.md` = Command-Name → in der Sitzung als `/ticket-abarbeiten` verfügbar. +- Frontmatter mit: + - `description` (**Pflicht**) — erscheint in der Command-Übersicht; + - `agent` (optional) — Agent, der den Command ausführt; + - `model` (optional) — Modell für die Ausführung. +- Body = **Template**. Argument-Platzhalter sind erlaubt und erwünscht: + - `$ARGUMENTS` — alles, was der Nutzer nach dem Command tippt; + - `$1` … `$n` — positionelle Argumente. + +**Minimalbeispiel:** + +```markdown +--- +description: Arbeitet das genannte beads-Ticket ab (claimen, umsetzen, schließen). +agent: build +--- + +Arbeite das Ticket $ARGUMENTS ab: zeige es mir, claime es, setze es um und +schließ es nach meiner Freigabe. +``` + +**Typische Fehler:** fehlendes Frontmatter, fehlende `description`, Command-Name +mit Leerzeichen/Umlauten (die später zum /slash-Namen wird). + +### `agents/` — Agenten-Definitionen + +**Struktur:** eine Markdown-Datei pro Agent, direkt in `agents/`. Dateiname = +Agentenname. + +**Anforderungen:** + +- Frontmatter mit: + - `description` (**Pflicht**) — sagt, wofür der Agent da ist; + - `mode` (**Pflicht**) — `primary` (per Agentenwechsel wählbar) oder + `subagent` (per @mention und automatisch über das Task-Tool startbar); + - `model`, `temperature` (optional); + - Permission-/Tool-Profil (optional, aber für Subagents empfohlen) — z. B. + ein Read-only-Prüfer ohne Edit/Bash. +- Body = Systemprompt des Agenten. + +**Harte Sicherheitsregeln (Guard prüft mit):** + +1. **Subagent-Fähigkeit bleibt erhalten:** keine Definition darf das Task-Tool + bzw. die Delegation an Subagents so einschränken, dass Subagents nicht mehr + startbar wären. Spezialisierung ja — die Fähigkeit von Agenten, selbst zu + delegieren und zu parallelisieren, wird nie verbaut. +2. **Niemals Rechte ausweiten:** Permission-Profile dürfen innerhalb des + verwalteten Regelwerks (Managed-Layer) nur **einschränken**, nie erlauben, + was der Managed-Layer verweigert. Provider-Lock und Permission-Regelwerk + gelten unabhängig vom aktiven Agenten weiter. + +**Minimalbeispiel (Read-only-Subagent):** + +```markdown +--- +description: Prüft Ergebnisse gegen Abnahme-Kriterien, ohne selbst zu ändern. +mode: subagent +temperature: 0.1 +tools: + - read + - grep + - glob +--- + +Du bist ein Read-only-Prüfer. Gleiche das vorgelegte Ergebnis gegen die +Abnahme-Kriterien ab und berichte nur — du editierst und schreibst nichts. +``` + +**Typische Fehler:** fehlende `mode`, `mode` mit ungültigem Wert, Frontmatter +ohne `description`. + +### `mcp/` — MCP-Server-Fragmente + +**Struktur:** eine YAML-Datei pro Server: `mcp/.yaml`. Jede Datei +ist ein **Fragment für den `mcp`-Konfigurationsschlüssel** — der Server-Name +steht als Schlüssel, darunter die Definition. Die Fragmente werden auf dem +Controller in die verwaltete Konfiguration (Managed-Layer) gemerged — MCPs sind +Werkzeuge und damit sicherheitsrelevant, sie gehören in den admin-kontrollierten +Layer, nicht auf die nutzerbeschreibbare Ebene. + +**Anforderungen:** + +- **Standard ist remote/streamable** mit OAuth: `type: remote` plus `url`; + die Anmeldung läuft zur Laufzeit einmalig pro Nutzer über dessen + Microsoft-Konto — identitätsgebunden. Ein OAuth-Server braucht daher **kein** + Credential-Feld im Fragment. +- `enabled` (optional) — Standard ist an. +- `local`-Server (`command`/`env`) nur als dokumentierte Ausnahme. +- **Secrets niemals im Repo — ohne Ausnahme.** Wo ein statischer Key nötig + ist (Nicht-OAuth-Ausnahme), steht im Fragment nur ein Platzhalter der Form + `` ${VAULT:} ``; der echte Key liegt im Vault des Fleet-Repos und + wird erst beim Merge auf dem Controller substituiert. Im Repo bleibt nie ein + Secret. + +**Minimalbeispiel (OAuth-Standardfall):** + +```yaml +# mcp/zugferd-service.yaml +zugferd-service: + type: remote + url: https://mcp.example.az.local/zugferd + enabled: true +``` + +**Typische Fehler:** Server-Name fehlt (Datei ist keine Fragment-Struktur), +fehlende `url`, `type` fehlt bei remote, ein Secret im Klartext (Guard bricht +ab — auch in Kommentaren), Platzhalter in anderer Syntax als `${VAULT:…}`. + +--- + +## Trennung Content / Mechanismus + +| Zuständigkeit | Repo | +|---|---| +| **Inhalte** (Skills, Commands, Agents, MCP-Fragmente) | **az-agent-defaults** (dieses Repo) | +| **Mechanismus** (Guard-Engine, Auslieferung/Spiegel, Drift-Reparatur, Vault-Substitution) | **az-fleet** | + +Konsequenzen für Contributors: + +- Dieses Repo enthält **keine** Auslieferungs-Logik, kein Playbook, kein Secret. +- Skills, Commands und Agenten-Definitionen werden als **exakter + Nutzerebene-Spiegel** ausgeliefert (inklusive Entfernen gelöschter Artefakte). +- MCP-Fragmente werden auf dem Controller in den **Managed-Layer** gemerged und + unterliegen dessen Admin-ACL. +- Der Stand dieses Repos wird über einen **Repo-Ref gepinnt** (Default: `main`). + Jeder Rollout ist damit deterministisch reproduzierbar; die Pin-Logik lebt in + `az-fleet`. + +## `tests/fixtures/` — Testgegenstände, nie ausgeliefert + +Guard-Tests brauchen gültige und ungültige Artefakt-Exemplare als +Testgegenstände. Diese **Fixtures** leben unter `tests/fixtures/` — denn die +Delivery-Rolle liest **nur die vier Typ-Verzeichnisse**, also kann unter +`tests/fixtures/` nichts „mitschwimmen" und versehentlich ausgeliefert werden. +(Sonntags-Entscheidung: bewusst kein eigener Auslieferungs-Ausschluss-Mechanismus, +sondern Trennung durch das Lese-Muster der Delivery-Rolle.) + +Konvention: je Artefakt-Typ ein Unterordner, darin `valid/`- und +`invalid/`-Exemplare, an denen der Guard durch- bzw. abbricht. + +``` +tests/fixtures/ +├── skills/valid/… skills/invalid/… +├── commands/valid/… commands/invalid/… +├── agents/valid/… agents/invalid/… +└── mcp/valid/… mcp/invalid/… +``` + +**Regel:** alles unter `tests/fixtures/` ist Testgegenstand und wird **nie +ausgeliefert** — nichts daraus in die Typ-Verzeichnisse schieben; umgekehrt +sind echte Artefakte dort fehl am Platz. + +--- + +## Beitrags-Kurzanleitung + +1. Richtiges Verzeichnis anhand der Tabelle oben wählen. +2. Artefakt gemäß Guard-Regeln des Typs anlegen (Minimalbeispiel als Vorlage). +3. Prüfen: erfüllt das Artefakt **alle** Pflichtpunkte der Checkliste seines Typs? + Wenn unsicher — die Checklisten sind vollständig; es braucht kein + Architektur-Wissen. +4. Commit/PR wie gewohnt. Der Guard läuft als Pre-Flight beim nächsten + Rollout in `az-fleet`; erst nach Rollout und App-Neustart ist das Artefakt + auf den Workstations. diff --git a/agents/.gitkeep b/agents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/commands/.gitkeep b/commands/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/mcp/.gitkeep b/mcp/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/skills/.gitkeep b/skills/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/fixtures/.gitkeep b/tests/fixtures/.gitkeep new file mode 100644 index 0000000..e69de29