Leitfaden

Eigenen Stack erstellen

Ein Prozess, jede Technologie: der Vertrag, den ein Layer-Plugin erfüllt.
Das Plugin aiup-core ist Stack-unabhängig: Es erstellt die Anforderungen, das Entitätsmodell, die Use Cases und die Testfälle, und es steuert die Konstruktion mit /stack, /use-case-implement, /use-case-test und /use-case-coverage, für eine Testfall-Journey mit /test-case-implement und /test-case-coverage. Die Technologie kommt aus Layer-Plugins, je eines pro Technologie einer technischen Schicht. Ist Ihre nicht dabei, beschreibt dieser Leitfaden, was ein Layer-Plugin mitbringen muss: einen Build-Skill und einen Test-Skill, eine references/layer.md, die die Schicht beschreibt, eine Übergabe an die nächste Schicht und die Markierungen, die jeden Test auf seinen Use Case zurückführen.
Arbeitsteilung

Layer-Plugin oder kombiniertes Stack-Plugin #

Der AI Unified Process (AIUP) stellt die Anforderungen ins Zentrum. Alles vor dem Code ist für jedes Team gleich; alles, was von einem Framework, einer Persistenztechnologie oder einem Testwerkzeug abhängt, gehört in ein Plugin. Seit Marketplace 3.0 fügt man eine Technologie am besten als Layer-Plugin hinzu.

Der Core verantwortet die Spezifikationen und die Regeln #

aiup-core schreibt den Anforderungskatalog, das Entitätsmodell, das Use-Case-Diagramm, die Use-Case-Spezifikationen und die End-to-End-Testfälle. Keines dieser Dokumente nennt ein Framework, und Ihr Plugin darf sie nie umschreiben. Für die Konstruktion verantwortet aiup-core auch die Orchestrierung und die Regeln, die für jede Schicht gelten: /use-case-implement prüft den Status, liest die Eingaben, gleicht bestehenden Code ab und fragt bei Lücken in der Spezifikation nach; /use-case-test entscheidet, welche Schicht was testet; /use-case-coverage prüft das Ergebnis mit einem Agenten, der nur liest.

Ein Layer-Plugin verantwortet eine Technologie #

Ein Layer-Plugin deckt eine Technologie einer technischen Schicht ab, zum Beispiel jOOQ für die Persistenz oder Angular für das UI. Ein Projekt kombiniert ein Plugin pro Schicht, und /stack hält die Kombination in der Stack-Datei fest, docs/architecture/stack.md. So lässt sich etwa eine REST-API mit Spring Boot und jOOQ ohne UI ausdrücken. Ein Projekt verwendet entweder Layer-Plugins oder ein kombiniertes Stack-Plugin, nie beides.

Referenzimplementierungen #

Nutzen Sie die Layer-Plugins im Marketplace-Repository als Referenzimplementierungen. Kopieren Sie dasjenige, das Ihrer Schicht am nächsten kommt: aiup-jooq ist ein kompaktes Persistenz-Plugin mit einem Build- und einem Test-Skill, aiup-spring-boot zeigt drei Schichten in einem Plugin und aiup-playwright eine E2E-Schicht ohne Build-Skill.

aiup-flywayMigration: /flyway-schema
aiup-jooqPersistenz: /jooq-persistence, /jooq-persistence-test
aiup-jpaPersistenz: /jpa-persistence, /jpa-persistence-test
aiup-spring-bootService, API und Client: /spring-service, /spring-rest, /spring-client, /spring-service-test, /spring-rest-test, /spring-client-test
aiup-vaadinUI und E2E: /vaadin-flow-ui, /hilla-ui, /vaadin-flow-ui-test, /hilla-ui-test, /vaadin-e2e-test
aiup-angularUI: /angular-ui, /angular-ui-test
aiup-playwrightE2E für TypeScript: /playwright-e2e-test
Wann stattdessen ein kombiniertes Stack-Plugin passt. Ist die Architektur in vertikalen Schnitten statt in horizontalen Schichten organisiert, bleibt ein kombiniertes Stack-Plugin die richtige Form: aiup-blazor-dotnet bleibt dauerhaft kombiniert, weil seine Vertical Slice Architecture den Handler und den Datenzugriff eines Use Case in einem Schnitt hält. Siehe kombinierte Stack-Plugins weiter unten.
Der Vertrag

Was ein Layer-Plugin mitbringt #

Ein Layer-Plugin bringt für seine Schicht einen Build-Skill und einen Test-Skill mit, benannt als <technologie>-<schicht> und <technologie>-<schicht>-test, etwa jooq-persistence und jooq-persistence-test. /use-case-implement führt die Build-Skills von unten nach oben aus, /use-case-test die Test-Skills ab der Integrationsschicht aufwärts, und jeder Skill läuft auch für sich allein.

Die sechs Schichten #

Ihr Plugin füllt eine dieser Schichten, oder mehrere, wenn eine Technologie sie überspannt, wie Spring Boot bei Service und API.

MigrationVersionierte Schemaänderungen aus dem Entitätsmodell
PersistenceDatenzugriff: Abfragen, Repositories, Entity-Mapping, Projektionen in Records
ServiceGeschäftslogik: Transaktionen, Geschäftsregeln, Orchestrierung
APIEntfernter Vertrag für einen separaten Client: Endpoints, DTOs, Fehlerformat
UIViews, Formulare, Grids, Navigation
E2EBrowsertests eines Use Case oder einer Testfall-Journey

API, UI und Service sind die Einstiegsschichten, über die ein Akteur das System erreicht. Ein Use Case kann in einer optionalen Zeile «Schichten:» die Einstiegsschichten nennen, die ihn anbieten (UI, API oder Service allein); /use-case-implement baut nur diese, /use-case-test testet nur diese, und die Abdeckungsprüfung meldet keine Lücke für eine Schicht, die die Zeile weglässt.

  1. Ein Build-Skill #

    Pflicht für jede Schicht ausser E2E. Baut eine Schicht eines Use Case.

    /use-case-implement UC-001     # alle Schichten, von unten nach oben
    /jooq-persistence UC-001  # eine Schicht, direkt ausgeführt

    Jeder Layer-Skill folgt demselben Gerüst: Instructions, Scope (was er übernimmt, was er erzeugt, was er nie anfasst), Run Directly or from /use-case-implement, die Technologie-Abschnitte samt der Stelle, an der die Markierung einer Geschäftsregel in dieser Schicht steht, Markers, DO NOT, Workflow, Handover und Resources. Modul und Package nimmt er aus der Spalte Location seiner Zeile in der Stack-Datei, und zuerst folgt er dem bestehenden Code des Projekts. Er greift nie über die nächste Schicht hinaus: Das UI fragt nicht die Datenbank ab, und eine fehlende Tabelle geht zurück an den Migrations-Skill, statt umgangen zu werden.

    Von /use-case-implement aufgerufen, übernimmt der Skill die Eingaben, die Statusprüfung, die Antworten zu Lücken in der Spezifikation und die Abgleichsregeln und wiederholt sie nicht. Direkt ausgeführt, liest er dieselben Eingaben, wendet dieselben Regeln an, baut nur seine Schicht und weist darauf hin, dass /use-case-implement alle Schichten ausführt. In beiden Fällen entscheidet er nach den Entscheidungsrechten von /use-case-implement: Er fragt vor einer Entscheidung, die sie dem Nachfragen vorbehalten, etwa einer neuen Abhängigkeit, trifft nie eine, die sie verbieten, und listet die Entscheidungen, die er allein getroffen hat, im Bericht unter Entscheidungen auf. Ein UI-Build-Skill liest zudem die optionale Zeile Mockup des Use Case als Vorgabe für das Layout, wie es der Abschnitt Mockups von /use-case-implement festlegt, und nennt in einer Zeile Mockup seiner Übergabe, was er übernommen und was er ausgelassen hat. Ein API-Build-Skill liest die optionale Zeile API des Use Case ebenso, wie es der Abschnitt API Contract von /use-case-implement festlegt, baut die verlinkte Operation so, wie ihr Vertrag es festlegt, und nennt sie in einer Zeile Contract seiner Übergabe. Die gemeinsamen Regeln stehen einmal, in aiup-core; verweisen Sie per Slash-Befehl darauf und kopieren Sie sie nicht in Ihren Skill.

  2. Ein Test-Skill #

    Pflicht für jede Schicht mit eigenem Code zum Testen. Benannt wie der Build-Skill plus -test.

    Ein Use Case wird einmal getestet, in der Integrationsschicht des Projekts: der obersten Schicht, deren Tests im Prozess gegen die echte Datenbank laufen. Ihr Test-Skill deckt das Hauptszenario ab, jeden alternativen Ablauf, jede Geschäftsregel mit ihrem erlaubten und ihrem abgelehnten Fall, die Vorbedingungen und die Nachbedingungen, gelesen aus dem gespeicherten Zustand. Die Schichten darunter erhalten keine eigenen Tests; Ihr Test-Skill muss deshalb wissen, welche Rolle er spielt:

    • Als Integrationsschicht – den ganzen Use Case über den eigenen Einstiegspunkt testen und jede Einheit melden, die er nicht erreicht, damit /use-case-test für genau diese Einheiten den Test-Skill der zuständigen Schicht ausführt.
    • Unter der Integrationsschicht – nur laufen, um bestehende Tests abzugleichen, für nicht erreichbare Einheiten oder wenn ein Aufruf die Schicht nennt, und nur eigene Logik testen, etwa einen Filter, einen Join oder das Paging.
    • Darüber, mit gemocktem Backend – testen, was das UI entscheidet und dass eine Ablehnung den Akteur mit der spezifizierten Meldung erreicht, nicht die Regel noch einmal.
    • Als zweite Einstiegsschicht – eine API neben einer Vaadin-Flow- oder Hilla-UI, die denselben Use Case anbietet, testet ihren eigenen Vertrag: das Hauptszenario über ihren Endpoint, die Antwort jedes alternativen Ablaufs und die Abbildung der Validierung, die Geschäftsregeln aber nicht noch einmal.
    • E2E – das Hauptszenario und die alternativen Abläufe, die ein Akteur sieht, wenn der E2E-Umfang in der Stack-Datei "Use cases and test cases" lautet; mit einer TC-XXX, ausgeführt von /test-case-implement, ein Journey-Test mit einem Schritt pro Zeile der Flow-Tabelle.
    Die Spezifikation ist das Orakel. Erwartete Werte stammen aus der Spezifikation und den Testdaten, nie aus einem Lauf des Codes. Ein Test, der dem Code widerspricht, bleibt rot und wird gemeldet; der Test-Skill ändert nie Produktionscode und schwächt, löscht oder deaktiviert eine solche Prüfung nie. /use-case-test verantwortet diese Regeln; ein direkt ausgeführter Test-Skill wendet sie ebenfalls an.
  3. references/layer.md #

    Pflicht. Eine Zeile, die die Schicht beschreibt, im Build-Skill oder im Test-Skill einer E2E-Schicht.

    /stack findet die installierten Layer-Skills, indem es */references/layer.md in den Skill-Ordnern des Projekts auflistet (.claude/skills/, .github/skills/, .codex/skills/, .agents/skills/, .cursor/skills/), im persönlichen Ordner ~/.claude/skills/ und, bei einer Installation aus einem Claude-Code-Marketplace, in den aktivierten Plugins aus ~/.claude/plugins/installed_plugins.json. Es listet diese Ordner direkt auf, denn sie sind versteckt, Tessl legt jeden Skill als Symlink nach .tessl/ an und trägt die Links im Managed Mode in .gitignore ein: Eine normale Suche mit ripgrep oder ein find ohne -L findet dort nichts. Wo der Host die Skills der Session auflistet, wie Claude Code, entscheidet diese Liste: Die layer.md eines deaktivierten, deinstallierten oder nur zwischengespeicherten Plugins zählt nicht, und ein Plugin-Skill läuft unter seinem Namen mit Präfix, etwa aiup-jooq:jooq-persistence. Ein Plugin, das aiup-core nicht kennt, funktioniert deshalb genauso wie eines, das mitgeliefert wird, ohne neues Core-Release. Aus der Spalte Detect erkennt /stack Ihre Technologie in einem bestehenden Projekt, aus der Spalte Tests run bestimmt es die Integrationsschicht.

    | Plugin | Layer | Skill | Test skill | Tests run | Detect in an existing project |
    | `aiup-jooq` | Persistence | `jooq-persistence` | `jooq-persistence-test` | in process, real database | `org.jooq:jooq`, `spring-boot-starter-jooq`, `jooq-codegen-maven` |
    LayerEine von Migration, Persistence, Service, API, UI, E2E
    SkillDer Ordnername des Build-Skills, oder – für eine E2E-Schicht
    Test skillDer Test-Skill, oder – wenn die Schicht keinen hat, wie bei einer Migration
    Tests runin process, real database; backend mocked; running application; oder – ohne Test-Skill
    DetectDie Abhängigkeiten, Dateien oder Annotationen, an denen man die Technologie erkennt; Belege aus dem Quellbaum zuerst

    Beginnen Sie die Zelle Detect mit Belegen aus dem Quellbaum, etwa einer @Route-Klasse, einer @BrowserCallable-Klasse oder einer angular.json. Nennt eine Zelle mehrere Arten von Belegen, entscheidet der Quellbaum, und eine Abhängigkeit, die auch ein anderer Skill nennt, ist für keinen der beiden ein Beleg: Vaadin Flow und Hilla teilen ihre Abhängigkeiten, also fragt /stack, statt zu raten.

    Ein Team-Skill ohne layer.md. Auch ein eigener Skill des Teams, ein mybatis-persistence oder ein Skill mit den Spring-Konventionen der Firma, ist ein Layer-Skill. Mit einer references/layer.md wird er gefunden wie ein Plugin aus dem Marketplace. Ohne sie zählt er, sobald Sie ihn in /stack für eine Schicht nennen; /stack fragt dann, wogegen seine Tests laufen (im Prozess gegen die echte Datenbank, mit simuliertem Backend oder gegen die laufende Anwendung), weil die Integrationsschicht davon abhängt, und schlägt vor, eine layer.md zu ergänzen, damit der nächste Lauf nicht mehr fragen muss. Der Leitfaden Writing a layer skill (Englisch) beschreibt den Vertrag.
  4. Die Übergabe #

    Pflicht. Der letzte Block im Bericht jedes Build-Skills.

    Die Schichten laufen Migration → Persistence → Service → API → UI. Jeder Build-Skill endet mit einem Handover-Block, der die Tabellen, Typen, Methodensignaturen oder Endpoints auflistet, die er angelegt oder geändert hat. /use-case-implement reicht ihn unverändert an die nächste Schicht weiter, die genau auf diesem Vertrag aufbaut, statt ein eigenes DTO zu erfinden. Eine Schicht ohne Arbeit sagt das in ihrer Übergabe. Für sich allein ausgeführt, ohne Übergabe, liest ein Skill den bestehenden Code der Schicht darunter; sein Scope sagt, wo.

    Handover from jooq-persistence (UC-001)
    - PersonRepository — src/main/java/com/example/app/person/PersonRepository.java
      - Optional<PersonForm> findById(long id)
      - boolean update(PersonForm person)   — false when the version is stale
      - boolean existsByEmail(String email) — UC-001 BR-003
    - record PersonForm(Long id, String firstName, String lastName, String email, int version)
  5. Markierungen in der Stack-Datei #

    Pflicht. Jeder Skill bringt eine references/markers.md mit und pflegt seine Zeilen im Projekt.

    Die Stack-Datei endet mit einer Markers-Tabelle: Layer, Skill, Kind (Code, Test oder Name) und die Markierung, nach der gesucht wird. Bei jedem Lauf prüft jeder Build- und Test-Skill, ob die Zeilen seines Skills mit seiner references/markers.md übereinstimmen, ergänzt fehlende, korrigiert abweichende und fasst keine andere Zeile an. Die Abdeckungsprüfung in aiup-core liest diese Tabelle statt einer festen Liste. Der Core muss Ihre Markierungen also nicht kennen, und Ihr Plugin braucht keinen eigenen Abdeckungs-Agenten.

    | Persistence | jooq-persistence-test | Test | `@UseCase(id = "UC-XXX", …)` on every repository test method |
    | Persistence | jooq-persistence-test | Name | `UC<id><Name>RepositoryTest` |
Argumente. Jeder Skill nimmt eine Use-Case-ID (UC-001) oder den Pfad der Spezifikationsdatei entgegen; der E2E-Test-Skill zusätzlich eine Testfall-ID (TC-001). Auf den Pfad darf ein Diff der Spezifikationsänderung folgen; ist er vorhanden, ist er die massgebliche Liste der Änderungen.
Eingaben

Was die Skills lesen #

Ein Layer-Plugin liest die Dokumente, die aiup-core schreibt, an den Orten, an denen aiup-core sie ablegt. Erfinden Sie kein zweites Format; die anforderungsgetriebene Kette funktioniert nur, wenn jedes Plugin dieselben Dateien liest.

Dateien #

docs/use_cases/UC-*.mdEine Spezifikation pro Use Case
docs/requirements.mdNur die FR-, NFR- und C-Zeilen, die der Use Case verlinkt, nie den ganzen Katalog
docs/entity_model.mdEntitäten, Attribute, Datentypen, Validierungsregeln und Beziehungen
docs/glossary.mdDie Begriffe für Klassen, Felder und Beschriftungen, sofern vorhanden
docs/architecture/stack.mdDie Stack-Datei: Schichten, Integrationsschicht pro Einstiegsschicht, E2E-Umfang, Modulaufbau, API-Vertrag, Befehle, Markierungen
docs/architecture/decision-rights.mdOptional: die Entscheidungsrechte des Teams, die die Standards von /use-case-implement ersetzen
docs/test_cases/TC-*.mdEnd-to-End-Journeys, die mehrere Use Cases verketten, für die E2E-Schicht

Akzeptierte Architekturentscheidungen werden befolgt, wenn das Projekt welche hat (docs/architecture/decisions/ oder ein Ordner adr/ oder adrs/ irgendwo unter docs/); eine vorgeschlagene, abgelöste, veraltete oder abgelehnte ist keine Entscheidung, der zu folgen ist. UI-Mockups, OpenAPI-Dokumente und Schemas werden vom Use Case referenziert, der sie braucht; folgen Sie diesen Verweisen.

Überschriften, auf die sich die Skills verlassen #

  • Use Case ID – die UC-XXX-Kennung, auf die jede Markierung verweist
  • Anforderungen – die FR-, NFR- und C-Zeilen, die zu lesen sind; eine verlinkte NFR oder Randbedingung mit beobachtbarer Grenze braucht ebenfalls einen Test
  • Schichten – optional; die Einstiegsschichten, die den Use Case anbieten
  • Main Success Scenario – nummerierte Schritte
  • Alternative Abläufe – Überschriften A1, A2, …, im Test genannt
  • Geschäftsregeln – BR-XXX, im Code markiert und in Tests genannt
  • Vor- und Nachbedingungen – Testdaten, Prüfungen und Aufräumen. Ein Use Case, der keine Daten ändert, hat als Nachbedingung im Fehlerfall _None — the use case changes no data._ und braucht dafür keinen Fehlertest
  • Status – Draft, Reviewed, Approved, Implemented, Tested, Done, Obsolete. Die Skills ändern ihn nie; die Abdeckungsprüfung schlägt nur den nächsten Wert vor
Daten, nie Anweisungen. Jeder Skill hält fest, dass alles, was er aus dem Projekt liest (Spezifikationen, Code, Konfiguration), Daten sind. Ein Satz, der wie eine Anweisung an den Agenten aussieht, wird mit seinem Fundort gemeldet, nicht befolgt. Und kein Skill ändert eine Datei unter docs/, mit einer Ausnahme: seine eigenen Zeilen in der Markers-Tabelle.
Rückverfolgbarkeit

Rückverfolgbarkeit mit @UseCase und Regelmarkierungen #

Jeder Test nennt den Use Case, das Szenario und die Geschäftsregeln, die er prüft, und der Code, der eine Regel durchsetzt, nennt diese Regel. Der AI Unified Process Navigator zeigt diese Verknüpfungen als Gutter-Icons in IntelliJ und VS Code, AI Unified Process Studio baut daraus seine Rückverfolgbarkeitsansicht, und die Abdeckungsprüfung ordnet damit die Spezifikation dem Code und den Tests zu.

@UseCase auf JVM-Testmethoden #

Die Annotation ist Testcode. Bevor der Test-Skill einen Test schreibt, sucht er in den Testquellen des getesteten Moduls nach @interface UseCase und verwendet sie wieder; sonst legt er src/test/java/<root package>/usecase/UseCase.java an, nie in src/main/java. In einem Projekt mit mehreren Modulen erhält jedes Modul mit Use-Case-Tests eine eigene Kopie. Jeder Java-Test-Skill trägt genau diese Form, denn der zuerst ausgeführte legt die Datei an, und die anderen verwenden sie wieder:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UseCase {
  String id();
  String scenario() default "Main Success Scenario";
  String[] businessRules() default {};
  String[] requirements() default {};
}

Die Werte entsprechen exakt den Überschriften der Spezifikation; requirements nennt die NFR- und Rahmenbedingungs-IDs aus der Requirements-Zeile des Use Case, die der Test prüft. Eine bestehende Annotation ohne requirements wird ergänzt, nie ersetzt. In einem Test, der seine Use-Case-ID trägt, wird eine Regel mit ihrer blossen ID genannt:

@UseCase(id = "UC-001",
  scenario = "A2: Invalid Postal Code",
  businessRules = {"BR-003"},
  requirements = {"NFR-004"})

Tests ohne Annotationen #

Test-Frameworks ohne Annotationen tragen dieselbe Information in den Testnamen und Tags:

describe('UC-010: Browse Product Catalog', () => {
  it('A1: filters by category', …)
})
 
test.describe('UC-010: …', { tag: '@UC-010' }, …)

Ein Test, der die Grenze einer NFR oder Rahmenbedingung prüft, nennt deren ID auf dieselbe Weise, etwa it('NFR-004: rejects a comment longer than 500 characters', …). Für eine andere Sprache verwenden Sie deren natives Gegenstück (ein Attribut, ein Trait, ein Tag) mit denselben Feldern: Use-Case-ID, Szenario, Geschäftsregeln und Anforderungen. Was Sie wählen, kommt in Ihre references/markers.md.

Markierungen von Geschäftsregeln im Code #

Der Build-Skill markiert den Code, der eine Geschäftsregel durchsetzt, mit einem qualifizierten Kommentar direkt über der Methode, der Abfragebedingung, dem Constraint oder dem Validator, und zwar während er die Regel implementiert:

// UC-001 BR-003: A guest must be at least eighteen years old.
-- UC-001 BR-003: …   # in einer SQL-Migration

Immer mit dem Use Case qualifiziert, weil Regeln pro Use Case nummeriert sind. Eine Regel, die in mehreren Schichten durchgesetzt wird, erhält die Markierung in jeder davon, und Ihr Skill sagt, wo sie in seiner Schicht steht. /use-case-implement verantwortet diese Regel; Ihr Skill nennt nur die Stelle. Halten Sie den ganzen Kommentar samt Einrückung innerhalb der Zeilenlänge des Formatters im Projekt (Spring Java Format bricht Kommentare bei 90 Spalten um): Eine Markierung, die der Build auf eine zweite Zeile umbricht, ist keine Zeile mehr, nach der man suchen kann, also kürzen Sie lieber die wiedergegebene Regel.

Namenskonventionen #

UC001RegisterPersonRepositoryTestPersistenztest eines Use Case
UC001RegisterGuestServiceTestServicetest eines Use Case
UC001RegisterGuestApiTestAPI-Test eines Use Case
UC001ManagePersonsTestServerseitiger UI-Test eines Use Case
UC001ManagePersonsEndpointTestVertragstest des Endpoints hinter einer Hilla-View
UC001ManagePersonsITBrowsertest eines Use Case (Java)
TC001CustomerOnboardingITJourney-Test (Java), mit (id, useCases) auf der Klasse
UC-001-manage-persons.spec.tsTestdatei eines Use Case (TypeScript)
UC-001-manage-persons.test.tsxHilla-View-Test eines Use Case
TC-001-<slug>.spec.tsJourney-Test, ein Schritt pro Zeile der Flow-Tabelle

Repositories und Services heissen nach der Domäne, nie nach einem Use Case: ein Repository pro Aggregat, ein Service pro Entität. Eine View heisst nach dem Use Case, den sie umsetzt, im Glossarbegriff des Akteurs, etwa ManagePersonsView.

Testdaten #

Die Testdaten gehören den Test-Skills; die Migrationsschicht schreibt keine. Eine bestehende Konvention des Projekts geht immer vor. Ohne eine solche verwenden die Layer-Plugins eine wiederholbare Flyway-Migration pro Use Case in den Testquellen. Flyways Standard-Location umfasst auch die Testressourcen, also braucht es weder ein Profil noch eine @TestPropertySource; wiederholbare Migrationen laufen nach allen versionierten und kollidieren nie mit der nächsten Produktionsversion:

src/test/resources/db/migration/R__uc001_register_guest.sql

Die Daten erfüllen die Vorbedingungen und enthalten die Zeilen, die eine Geschäftsregel ausschliessen muss, damit eine fehlende Bedingung einen Test scheitern lässt. Die Tests laufen gegen die Datenbank, auf der das Projekt läuft, nie gegen einen In-Memory-Ersatz mit anderem Dialekt. Daten, die ein Test anlegt, entfernt er beim Aufräumen, nie mit einem Delete-all. Ein Ablauf, dessen Auslöser die gemeinsamen Daten ausschliessen, etwa eine leere Liste, löscht diese Zeilen innerhalb einer Testtransaktion, die zurückgerollt wird, wo der Einstiegspunkt im Thread des Tests läuft (Browserless, MockMvc, ein Service-Aufruf); ein Browsertest überlässt diesen Ablauf der Integrationsschicht.

Änderungen

Abgleichen statt kopieren #

Ein neues Feature, ein Change Request und ein Bug enden am selben Ort: in einer geänderten Use-Case-Spezifikation. Für keinen davon gibt es einen eigenen Befehl. Man ändert die Spezifikation und führt /use-case-implement und /use-case-test erneut aus; deshalb muss jeder Layer-Skill den bestehenden Code seiner Schicht finden und an Ort und Stelle abgleichen. /use-case-implement und /use-case-test verantworten diese Regeln und geben sie an jede Schicht weiter; ein direkt ausgeführter Skill wendet sie selbst an.

Build-Skills #

  • Zuerst suchen. Nach den Namen, die die Spezifikation nahelegt, und nach bestehenden UC-XXX-Verweisen.
  • An Ort und Stelle ändern. Nie eine zweite View, einen zweiten Endpoint, Service, ein zweites Repository oder DTO für denselben Use Case anlegen.
  • Dem Diff folgen. Liegt ein Spezifikations-Diff bei, Änderung für Änderung abarbeiten. Eine entfernte Zeile heisst: Das beschriebene Verhalten muss gelöscht werden.
  • Markierungen nachführen. Eine BR-Markierung anpassen, wenn sich ihre Regel geändert hat, und sie zusammen mit dem Code einer weggefallenen Regel entfernen.
  • Nichts anderes anfassen. Kein beiläufiges Refactoring, Umbenennen oder Umgestalten.
  • Berichten. Auflisten, welche Dateien sich geändert haben und welche Spezifikationsänderung jede ausgelöst hat.

Test-Skills #

  • Zuerst suchen. Die bestehenden Tests des Use Case über die Testmarkierungen der Markers-Tabelle finden.
  • Aktualisieren statt duplizieren. Die bestehende Klasse erweitern; nie eine zweite Testklasse für denselben Use Case schreiben.
  • Die Spezifikation spiegeln. Tests für neue Abläufe und Regeln ergänzen, geänderte anpassen, Tests für weggefallenes Verhalten löschen.
  • Behalten, was noch gilt. Grüne Tests, die die Spezifikation weiterhin verlangt, unverändert lassen und die Testdaten anpassen, wenn sich die Datenanforderungen geändert haben.
  • Auf nachgeladene Daten warten. Ein Browsertest wartet nach jeder Navigation, bis ein Grid oder eine Liste mit Lazy Loading ihre Zeilen geladen hat, bevor er eine Zelle liest oder Zeilen zählt; Abfragen ohne Wiederholung sehen sonst eine leere Liste.
  • Die Klasse ausführen. Danach die ganze Testklasse laufen lassen, nicht nur die neuen Tests.
Warum das zählt. Eine parallele Implementierung ist der teuerste Fehler bei KI-generiertem Code: zwei Views für einen Use Case, nur eine davon getestet. Die Abdeckungsprüfung meldet sie als Abweichung, aber der Build-Skill sollte sie gar nicht erst erzeugen.
Bauen

Paketieren und veröffentlichen #

Ein Layer-Plugin ist ein Ordner mit Skills und seinen Manifesten. Kopieren Sie zu Beginn das Layer-Plugin, das Ihrem am nächsten kommt, und ersetzen Sie die Technologie, nicht die Struktur.

  1. Das Plugin anlegen #

    aiup-<technologie>/
      .claude-plugin/plugin.json  # Claude-Code-Manifest: name, description, version, author
      .tessl-plugin/plugin.json  # Tessl-Manifest
      plugin.json, mcp.json  # Agent-Plugins-Manifest und MCP-Konfiguration
      .mcp.json  # Dokumentationsserver für Ihre Technologie
      rules/mcp-servers.md  # wie man diese Server von Hand einrichtet
      skills/<technologie>-<schicht>/SKILL.md
      skills/<technologie>-<schicht>/references/layer.md
      skills/<technologie>-<schicht>/references/markers.md
      skills/<technologie>-<schicht>-test/SKILL.md
      skills/<technologie>-<schicht>-test/references/markers.md
      evals/  # Szenarien, die die Skills prüfen
  2. Jeden Skill schreiben #

    Jede SKILL.md beginnt mit einem Namen, der dem Ordner entspricht, und einer Beschreibung, die die auslösenden Formulierungen aufzählt («write the jOOQ repository», den Namen Ihres Frameworks) und sagt, dass der Skill normalerweise von /use-case-implement oder /use-case-test aufgerufen wird. Hosts wie Tessl installieren Skills Ordner für Ordner. Ein Skill verlinkt deshalb nur auf Dateien im eigenen Ordner, nennt einen anderen Skill per Slash-Befehl und findet die Datei eines anderen Skills mit einem Glob. Ein Skill-Ordner enthält nur .md- und .py-Dateien; packen Sie eine Beispielklasse in Markdown, wie es aiup-jooq mit seiner Testvorlage tut.

  3. Dokumentationsserver anbinden #

    Trainingsdaten von Modellen hinken Framework-Releases hinterher. Deklarieren Sie in .mcp.json MCP-Server für die Dokumentation Ihres Frameworks und weisen Sie die Skills an, sie zu konsultieren, wenn sie eingerichtet sind, und sonst auf ihre eigenen Dokumentationslinks zurückzugreifen. Tessl liefert keine MCP-Server-Definitionen aus; rules/mcp-servers.md erklärt deshalb, wie man sie von Hand ergänzt.

  4. Andere KI-Coding-Werkzeuge unterstützen #

    Damit das Plugin auch in Codex CLI, Cursor, GitHub Copilot, Gemini CLI und OpenCode läuft, ergänzen Sie das Agent-Plugins-Manifest (plugin.json und mcp.json im Plugin-Root) und das Tessl-Manifest und erhöhen alle drei Versionen gemeinsam. Siehe andere KI-Coding-Werkzeuge.

  5. Beitragen #

    Ein Layer-Plugin in Ihrem eigenen Repository funktioniert so, wie es ist: /stack findet es über seine references/layer.md, ohne Änderung an aiup-core, ebenso einen Skill im Skill-Ordner des Projekts oder in ~/.claude/skills/. Ein Claude-Code-Marketplace ist nur ein Git-Repository mit einer marketplace.json. Damit jedes Team es nutzen kann, eröffnen Sie einen Pull Request gegen das Marketplace-Repository: Dort ergänzt das Plugin auch seine Zeile in der Plugins-Tabelle des Layer-Katalogs in aiup-core, und die CI-Prüfungen halten diese Tabelle, die layer.md-Dateien und die Form von @UseCase synchron.

Die andere Form

Kombinierte Stack-Plugins #

Ein kombiniertes Stack-Plugin baut UI, Backend und Datenzugriff in einem einzigen /implement. Es passt zu einer Architektur, die sich nicht in horizontale Schichten teilen lässt, etwa vertikale Schnitte. Es liest die Stack-Datei nicht und wird nicht von /use-case-implement gesteuert; es bringt eigene Befehle mit, und ein Projekt installiert aiup-core und genau dieses eine Plugin.

aiup-blazor-dotnetBleibt dauerhaft kombiniert: Vertical Slice Architecture. /ef-migration, /implement, /dotnet-test, /bunit-test, /playwright-test
aiup-nestjs-nextjsVeraltet, abgelöst durch die Layer-Plugins aiup-drizzle, aiup-nestjs und aiup-nextjs, entfällt mit aiup-core 4.0.0
aiup-vaadin-jooqVeraltet, abgelöst durch die Layer-Plugins, entfällt mit aiup-core 4.0.0
aiup-angular-jpaVeraltet, abgelöst durch die Layer-Plugins, entfällt mit aiup-core 4.0.0
  1. Migration #

    Pflicht. Benannt nach dem Migrationswerkzeug: /ef-migration, /drizzle-migration.

    Liest das Entitätsmodell und die bestehenden Migrationen und schreibt die nächste versionierte Migration. Eine Schemaänderung ist immer eine neue Migration; eine bereits angewendete wird nie geändert.

  2. Implementieren #

    Pflicht. Heisst immer /implement.

    Liest dieselben Eingaben wie /use-case-implement und schreibt den vollständigen Schnitt eines Use Case, mit den Markierungen UC-XXX BR-YYY, und gleicht bestehenden Code nach den obigen Regeln ab. Er schreibt keine Tests und nennt am Ende den nächsten Befehl.

  3. Unit- und Integrationstests #

    Pflicht. Benannt nach dem Testwerkzeug: /dotnet-test, /bunit-test, /nest-test, /react-test.

    Eine Testklasse oder Testdatei pro Use Case, die die Spezifikation abdeckt statt den Code, mit den obigen Testmarkierungen.

  4. End-to-End-Tests #

    Pflicht. Heisst immer /playwright-test.

    Mit einer Use-Case-ID führt er die laufende Anwendung durch die Szenarien dieses Use Case; mit einer Testfall-ID schreibt er einen Journey-Test mit einem Schritt pro Zeile der Flow-Tabelle.

  5. Abdeckungsprüfung #

    Empfohlen. /coverage-check plus ein Agent, der nur liest, mit den Markierungen dieses Stacks.

    /use-case-coverage in aiup-core liest seine Markierungen aus der Stack-Datei, die ein kombiniertes Plugin nicht schreibt. Ein kombiniertes Plugin, das die Prüfung anbieten will, bringt deshalb eine eigene Kopie des Agenten mit, beschränkt auf Read, Grep und Glob, wie es aiup-vaadin-jooq und aiup-angular-jpa tun.

Vor der Auslieferung

Checkliste #

Installieren Sie Ihr Layer-Plugin neben aiup-core und den anderen Schichten eines kleinen Beispielprojekts und prüfen Sie dann jeden Punkt.

Gefunden

Installiert, wo der Host ihn findet, und aktiviert: /stack findet Ihre Skills über ihre references/layer.md, erkennt die Technologie am Quellbaum und trägt sie in die Layers-Tabelle ein.

Übergeben

/use-case-implement UC-001 führt Ihren Build-Skill an seiner Stelle aus, und die Schicht darüber baut auf seiner Übergabe auf, ohne zweites DTO.

Markierungen eingetragen

Nach dem ersten Lauf stehen Ihre Zeilen in der Markers-Tabelle, und /use-case-coverage UC-001 findet damit Ihren Code und Ihre Tests.

Einmal getestet

/use-case-test UC-001 testet den Use Case in der Integrationsschicht, und eine tiefere Schicht schreibt nur Tests für eigene Logik.

Jeder Test verfolgbar

Jeder Test nennt Use-Case-ID, Szenario und Geschäftsregeln, exakt passend zu den Überschriften der Spezifikation.

Zweiter Lauf ändert nichts

/use-case-implement zweimal auf eine unveränderte Spezifikation ändert nichts und legt keine neuen Dateien an; nach der Änderung eines alternativen Ablaufs ändern sich nur Code und Tests dieses Ablaufs.

Nächster Schritt

Bringen Sie Ihren Stack in den AI Unified Process #

AI Unified Process Studio schreibt die Spezifikationen, die Ihr Layer-Plugin liest. Fordern Sie eine Einladung an, oder nehmen Sie Kontakt auf, wenn Sie Unterstützung beim Entwurf eines Plugins für Ihre Architektur möchten.