The AI Unified Process (AIUP) keeps requirements at the center. Everything upstream of code is the same for every team; everything that depends on a framework, a persistence technology, or a test tool belongs to a plugin. Since marketplace 3.0, the recommended way to add a technology is a layer plugin.
aiup-core writes the requirements catalog, the entity model, the use case diagram, the use case specifications, and the end-to-end test cases. None of these mention a framework, and your plugin must never rewrite them. For construction, aiup-core also owns the orchestrators and the rules every layer shares: /use-case-implement checks the status, reads the inputs, reconciles existing code, and asks about specification gaps; /use-case-test decides which layer tests what; /use-case-coverage audits the result with a read-only agent.
A layer plugin covers one technology of one technical layer, for example jOOQ for persistence or Angular for the UI. A project combines one plugin per layer, and /stack records the combination in the stack file, docs/architecture/stack.md. That is how a REST API with Spring Boot and jOOQ and no UI becomes expressible. A project uses either layer plugins or one combined stack plugin, never both.
Use the layer plugins in the marketplace repository as reference implementations. Copy the one closest to your layer: aiup-jooq is a compact persistence plugin with one build and one test skill, aiup-spring-boot shows three layers in one plugin, and aiup-playwright an E2E layer without a build skill.
aiup-flywayMigration: /flyway-schemaaiup-jooqPersistence: /jooq-persistence, /jooq-persistence-testaiup-jpaPersistence: /jpa-persistence, /jpa-persistence-testaiup-spring-bootService, API, and Client: /spring-service, /spring-rest, /spring-client, /spring-service-test, /spring-rest-test, /spring-client-testaiup-vaadinUI and E2E: /vaadin-flow-ui, /hilla-ui, /vaadin-flow-ui-test, /hilla-ui-test, /vaadin-e2e-testaiup-angularUI: /angular-ui, /angular-ui-testaiup-playwrightE2E for TypeScript: /playwright-e2e-testA layer plugin brings a build skill and a test skill for its layer, named <technology>-<layer> and <technology>-<layer>-test, such as jooq-persistence and jooq-persistence-test. /use-case-implement runs the build skills bottom-up, /use-case-test runs the test skills from the integration layer up, and every skill also runs on its own.
Your plugin fills one of these layers, or several when one technology spans them, as Spring Boot does for service and API.
MigrationVersioned schema changes from the entity modelPersistenceData access: queries, repositories, entity mapping, projections into recordsServiceBusiness logic: transactions, business rules, orchestrationAPIRemote contract for a separate client: endpoints, DTOs, error formatUIViews, forms, grids, navigationE2EBrowser tests of a use case or a test case journeyAPI, UI, and Service are the entry layers, where an actor reaches the system. A use case may name the entry layers that offer it in an optional Layers line (UI, API, or Service alone); /use-case-implement builds only those, /use-case-test tests only those, and the coverage audit reports no gap for a layer the line leaves out.
Required for every layer except E2E. Builds one layer of one use case.
Every layer skill follows the same skeleton: Instructions, Scope (what it consumes, what it produces, what it never touches), Run Directly or from /use-case-implement, the technology sections with where the business rule marker goes in this layer, Markers, DO NOT, Workflow, Handover, and Resources. It takes the module and package from the Location column of its row in the stack file and follows the existing code of the project first. It never reaches past the next layer: the UI does not query the database, and a missing table goes back to the migration skill instead of being worked around.
Run from /use-case-implement, the skill inherits the inputs, the status check, the answers to the specification gaps, and the reconcile rules, and does not repeat them. Run directly, it reads the same inputs, applies the same rules, builds its layer only, and says that /use-case-implement runs all layers. Either way, it takes decisions by the decision rights of /use-case-implement: it asks before a decision they reserve, such as a new dependency, never takes one they forbid, and lists the decisions it took alone under Decisions in its report. A UI build skill also reads the use case's optional Mockup line as layout input, as the section Mockups of /use-case-implement defines, and names what it followed and left out in a Mockup line of its Handover. An API build skill reads the use case's optional API line the same way, as the section API Contract of /use-case-implement defines, builds the linked operation as its contract says, and names it in a Contract line of its Handover. The shared rules live once, in aiup-core; refer to them by slash command and do not copy them into your skill.
Required for every layer with code of its own to test. Named after the build skill plus -test.
A use case is tested once, in the project's integration layer: the topmost layer whose tests run in process against the real database. Its test skill covers the main success scenario, every alternative flow, every business rule with its allowed and its rejected case, the preconditions, and the postconditions read back from the persisted state. The layers below get no tests of their own, so your test skill must know which role it plays:
Required. One row that describes the layer, in the build skill, or in the test skill of an E2E layer.
/stack discovers the installed layer skills by listing */references/layer.md in the project's skill folders (.claude/skills/, .github/skills/, .codex/skills/, .agents/skills/, .cursor/skills/), in the personal folder ~/.claude/skills/, and, for a Claude Code marketplace install, in the enabled plugins of ~/.claude/plugins/installed_plugins.json. It lists those folders directly, because they are hidden, Tessl links each skill as a symlink into .tessl/, and in its managed mode lists the links in .gitignore: a default ripgrep search or a find without -L finds nothing there. Where the host lists the session's skills, as Claude Code does, that list decides: the layer.md of a disabled, uninstalled, or merely cached plugin does not count, and a plugin skill runs by its prefixed name, such as aiup-jooq:jooq-persistence. So a plugin that aiup-core has never heard of works as well as one it ships with, without a core release. /stack reads the Detect column to recognise your technology in an existing project and the Tests run column to decide the integration layer.
LayerOne of Migration, Persistence, Service, API, UI, E2ESkillThe build skill's folder name, or – for an E2E layerTest skillThe test skill, or – when the layer has none, as for a migrationTests runin process, real database; backend mocked; running application; or – without a test skillDetectThe dependencies, files, or annotations that show the technology is in use; source-tree evidence firstLead the Detect cell with evidence from the source tree, such as a @Route class, a @BrowserCallable class, or an angular.json. Where a cell lists several kinds of evidence, the source tree decides, and a dependency that another skill names as well is no evidence for either: Vaadin Flow and Hilla share their dependencies, so /stack asks instead of guessing.
Required. The last block of every build skill's report.
Layers run migration → persistence → service → API → UI. Each build skill ends with a Handover that lists the tables, types, method signatures, or endpoints it created or changed, and /use-case-implement passes it unchanged to the next layer, which builds on exactly that contract instead of inventing its own DTO. A layer with nothing to do says so in its Handover. Run on its own, without a Handover, a skill reads the existing code of the layer below; its Scope says where.
Required. Each skill ships references/markers.md and keeps its rows in the project.
The stack file ends with a Markers table: Layer, Skill, Kind (Code, Test, or Name), and the marker to grep for. On every run, each build and test skill checks that the rows for its skill match its references/markers.md, adds the missing ones, corrects the ones that differ, and touches no other row. The coverage auditor in aiup-core reads that table instead of a fixed list, so core needs no knowledge of your markers, and your plugin needs no coverage agent of its own.
A layer plugin reads the documents aiup-core writes, in the places aiup-core writes them. Do not invent a second format; the requirements-driven chain only works when every plugin reads the same files.
docs/use_cases/UC-*.mdOne specification per use casedocs/requirements.mdOnly the FR, NFR, and C rows the use case links, never the whole catalogdocs/entity_model.mdEntities, attributes, data types, validation rules, and relationshipsdocs/glossary.mdThe terms to name classes, fields, and labels with, when it existsdocs/architecture/stack.mdThe stack file: layers, integration layer per entry layer, E2E scope, module layout, API contract, commands, markersdocs/architecture/decision-rights.mdOptional: the team's decision rights, which replace the defaults of /use-case-implementdocs/test_cases/TC-*.mdEnd-to-end journeys that chain several use cases, for the E2E layerAccepted architecture decision records are followed when the project has them (docs/architecture/decisions/, or an adr/ or adrs/ folder anywhere in docs/); a proposed, superseded, deprecated, or rejected one is no decision to follow. UI mockups, OpenAPI documents, and schemas are referenced from the use case that needs them; follow those references.
Every test names the use case, scenario, and business rules it verifies, and the code that enforces a rule names that rule. The AI Unified Process Navigator shows these links as gutter icons in IntelliJ and VS Code, AI Unified Process Studio builds its traceability view from them, and the coverage audit uses them to map the specification onto code and tests.
The annotation is test code. Before writing a test, the test skill searches the test sources of the module under test for @interface UseCase and reuses it; otherwise it creates src/test/java/<root package>/usecase/UseCase.java, never in src/main/java. In a multi-module project, every module that holds use case tests gets its own copy. Every Java test skill carries exactly this shape, because whichever one runs first creates the file and the others reuse it:
The values match the headings of the specification exactly; requirements names the NFR and constraint IDs from the use case's Requirements line that the test asserts. An existing annotation without requirements is extended, never replaced. Inside a test that carries its use case ID, a rule is named by its bare ID:
Test frameworks without annotations carry the same information in the test names and tags:
A test that asserts the limit of an NFR or constraint names its ID the same way, as in it('NFR-004: rejects a comment longer than 500 characters', …). For another language, use its native equivalent (an attribute, a trait, a tag) with the same fields: use case ID, scenario, business rules, and requirements. Whatever you choose goes into your references/markers.md.
The build skill marks the code that enforces a business rule with a qualified comment, directly above the method, query condition, constraint, or validator, while it implements the rule:
Always qualified with the use case, because rules are numbered per use case. A rule enforced in several layers gets the marker in each, and your skill says where it goes in its layer. /use-case-implement owns this rule; your skill only names the place. Keep the whole comment, indentation included, within the line length of the project's formatter (Spring Java Format wraps comments at 90 columns): a marker the build breaks onto a second line is no longer one line to grep, so shorten the restated rule instead.
UC001RegisterPersonRepositoryTestPersistence test of one use caseUC001RegisterGuestServiceTestService test of one use caseUC001RegisterGuestApiTestAPI test of one use caseUC001ManagePersonsTestServer-side UI test of one use caseUC001ManagePersonsEndpointTestEndpoint contract test behind a Hilla viewUC001ManagePersonsITBrowser test of one use case (Java)TC001CustomerOnboardingITJourney test (Java), annotated (id, useCases) on the classUC-001-manage-persons.spec.tsTest file of one use case (TypeScript)UC-001-manage-persons.test.tsxHilla view test of one use caseTC-001-<slug>.spec.tsJourney test, one step per Flow rowRepositories and services are named after the domain, never after a use case: a repository per aggregate, a service per entity. A view is named after the use case it realizes, in the actor's glossary term, such as ManagePersonsView.
The test skills own the test data; the migration layer writes none. An existing convention of the project always comes first. Without one, the layer plugins use one repeatable Flyway migration per use case in the test sources. Flyway's default location covers the test resources too, so neither a profile nor a @TestPropertySource is needed; repeatable migrations run after every versioned one and never collide with the next production version:
The data satisfies the preconditions and contains the rows a business rule must exclude, so a missing condition makes a test fail. Tests run against the database the project runs on, never an in-memory substitute with another dialect. Data a test creates is removed in its cleanup, never with a delete-all. A flow whose trigger the shared data rules out, such as an empty list, deletes those rows inside a test transaction that rolls back, where the entry point runs in the test's thread (Browserless, MockMvc, a service call); a browser test leaves that flow to the integration layer.
A new feature, a change request, and a bug all end in the same place: a changed use case specification. There is no separate command for any of them. The user edits the specification and runs /use-case-implement and /use-case-test again, so every layer skill must find the existing code of its layer and reconcile it in place. /use-case-implement and /use-case-test own these rules and pass them to each layer; a skill run directly applies them itself.
A layer plugin is a folder of skills with its manifests. Start by copying the layer plugin closest to yours and replace the technology, not the structure.
Each SKILL.md starts with a name that matches its folder and a description that lists the phrases that should trigger it ("write the jOOQ repository", the name of your framework) and says it is normally run by /use-case-implement or /use-case-test. Hosts such as Tessl install skills one folder at a time, so a skill links only to files inside its own folder, names another skill by slash command, and finds a file of another skill with a glob. A skill folder holds only .md and .py files; wrap an example class in Markdown, as aiup-jooq does with its test template.
Model training data lags behind framework releases. Declare MCP servers for your framework's documentation in .mcp.json and tell the skills to consult them when configured, and to fall back to their own documentation links otherwise. Tessl does not ship MCP server definitions, so rules/mcp-servers.md explains how to add them by hand.
To run in Codex CLI, Cursor, GitHub Copilot, Gemini CLI, and OpenCode as well, add the Agent Plugins manifest (plugin.json and mcp.json at the plugin root) and the Tessl manifest, and bump all three versions together. See other AI coding tools.
A layer plugin in your own repository works as it is: /stack finds it by its references/layer.md, without a change to aiup-core, and so does a skill in the project's skill folder or in ~/.claude/skills/. A Claude Code marketplace is just a Git repository with a marketplace.json. To make it available to every team, open a pull request against the marketplace repository: there the plugin also adds its row to the Plugins table of the layer catalog in aiup-core, and the CI checks keep that table, the layer.md files, and the @UseCase shape in step.
A combined stack plugin builds UI, backend, and data access in one /implement. It fits an architecture that does not split into horizontal layers, such as vertical slices. It does not read the stack file and is not driven by /use-case-implement; it ships its own commands, and a project installs aiup-core plus exactly that one plugin.
aiup-blazor-dotnetStays combined for good: Vertical Slice Architecture. /ef-migration, /implement, /dotnet-test, /bunit-test, /playwright-testaiup-nestjs-nextjsDeprecated, superseded by the layer plugins aiup-drizzle, aiup-nestjs, and aiup-nextjs, removed with aiup-core 4.0.0aiup-vaadin-jooqDeprecated, superseded by the layer plugins, removed with aiup-core 4.0.0aiup-angular-jpaDeprecated, superseded by the layer plugins, removed with aiup-core 4.0.0Required. Named after the migration tool: /ef-migration, /drizzle-migration.
Reads the entity model and the existing migrations and writes the next versioned migration. A schema change is always a new migration; an applied one is never edited.
Required. Always called /implement.
Reads the same inputs as /use-case-implement and writes the complete slice of one use case, with the UC-XXX BR-YYY markers, reconciling existing code by the rules above. It writes no tests and ends by naming the next command.
Required. Named after the test tool: /dotnet-test, /bunit-test, /nest-test, /react-test.
One test class or file per use case, covering the specification rather than the code, with the test markers above.
Required. Always called /playwright-test.
With a use case ID it drives the running application through that use case's scenarios; with a test case ID it writes one journey test with one step per Flow row.
Recommended. /coverage-check plus a read-only agent with this stack's markers.
/use-case-coverage in aiup-core reads its markers from the stack file, which a combined plugin does not write. A combined plugin that wants the audit therefore ships its own copy of the agent, restricted to Read, Grep, and Glob, as aiup-vaadin-jooq and aiup-angular-jpa do.
Install your layer plugin next to aiup-core and the other layers of a small sample project, then check each point.
Installed where the host finds it and enabled, /stack finds your skills by their references/layer.md, detects the technology from the source tree, and writes them into the Layers table.
/use-case-implement UC-001 runs your build skill in its place, and the layer above builds on its Handover without a second DTO.
After the first run, your rows are in the Markers table, and /use-case-coverage UC-001 finds your code and tests by them.
/use-case-test UC-001 tests the use case in the integration layer, and a lower layer writes only tests of logic of its own.
Each test names its use case ID, scenario, and business rules, matching the specification's headings exactly.
Running /use-case-implement twice on an unchanged specification changes nothing and creates no new files; after editing one alternative flow, only that flow's code and tests change.
AI Unified Process Studio writes the specifications your layer plugin reads. Request an invitation, or get in touch if you want help designing a plugin for your architecture.