From bpmn-to-code
Generates Kotlin BpmnValidationRule implementations from a BPMN style guide for automated enforcement in CI tests. Use when converting style guide rules to executable test validations.
How this skill is triggered — by the user, by Claude, or both
Slash command
/bpmn-to-code:generate-rules-to-enforce-bpmn-styleguideThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Generate Kotlin `BpmnValidationRule` implementations for the deterministic rules in `BPMN_STYLE_GUIDE.md`. The output is a single file that plugs into `bpmn-to-code-testing`'s `BpmnValidator`.
Generate Kotlin BpmnValidationRule implementations for the deterministic rules in BPMN_STYLE_GUIDE.md. The output is a single file that plugs into bpmn-to-code-testing's BpmnValidator.
validation includes a deterministic half (deterministic or hybrid). Pure-LLM rules stay in the style guide for /validate-bpmn-style.hybrid rules, generate the deterministic half only. Mention in a comment on the generated class that the full rule also has a semantic half enforced by /validate-bpmn-style.requireNotNull() instead of !! (project convention).bpmn-to-code-core/src/main/kotlin/io/miragon/bpmn/domain/validation/rules/InvalidIdentifierRule.kt as the structural template../gradlew compileKotlin (or the user's module-specific task).For rule bodies, read the actual domain classes under bpmn-to-code-core/src/main/kotlin/io/miragon/bpmn/domain/shared/ — don't trust static summaries, the model evolves. ProcessModel is the entry point.
bpmn-to-code-testing SetupGenerated rules depend on io.miragon:bpmn-to-code-testing. If it's not on the user's classpath, the code won't compile — abort before writing anything.
Glob for build files at repo root and one level below: build.gradle, build.gradle.kts, pom.xml, */build.gradle*, */pom.xml.
Grep each for bpmn-to-code-testing.
No match → abort and show how to add it:
// build.gradle.kts
dependencies {
testImplementation("io.miragon:bpmn-to-code-testing:<latest>")
}
<!-- pom.xml -->
<dependency>
<groupId>io.miragon</groupId>
<artifactId>bpmn-to-code-testing</artifactId>
<version><latest></version>
<scope>test</scope>
</dependency>
Tell the user to add it and re-run.
Multiple module matches → ask which one hosts the rules.
BPMN_STYLE_GUIDE.md (current dir, then git root). Missing → suggest /build-bpmn-styleguide.<!-- rule:<slug> --> anchor. yaml``` fenced block as the rule metadata.category, severity, applies-to, validation, pattern, engine (optional).For each rule, decide whether to generate Kotlin for it:
validation | Generate? | Note |
|---|---|---|
deterministic | Yes | Full rule goes into Kotlin. |
hybrid | Partial | Generate the deterministic half; document that the semantic half stays for /validate-bpmn-style. |
llm | No | Skip. Rule stays in the style guide. |
Present the classification as a table and pause for user confirmation:
| Rule | Category | Validation | Generate? | Reason |
|---------------------|--------------------------|---------------|-----------|--------|
| element-id-format | technical-configuration | deterministic | Yes | Regex on FlowNodeDefinition.id |
| service-task-topic | technical-configuration | hybrid | Partial | Regex half generated; semantic half stays in style guide |
| task-naming | business-modeling | llm | No | Semantic only — use /validate-bpmn-style |
| gateway-flow-labels | technical-configuration | deterministic | Yes | Presence check on SequenceFlowDefinition.flowName |
Produce a single Kotlin file: one class per generated rule + an aggregator.
File header:
// Generated from BPMN_STYLE_GUIDE.md by /generate-rules-to-enforce-bpmn-styleguide.
// Re-run the skill after editing the style guide to keep this file in sync.
Per-rule class (template — follow InvalidIdentifierRule.kt for shape):
/**
* element-id-format (deterministic)
* Category: technical-configuration
*/
class ElementIdFormatRule : BpmnValidationRule {
override val id = "element-id-format"
override val severity = Severity.ERROR
override fun validate(context: ValidationContext): List<ValidationViolation> {
val pattern = Regex("^(serviceTask|userTask|...)_[A-Z][a-zA-Z0-9]*$")
return context.model.flowNodes
.filter { node ->
val nodeId = requireNotNull(node.id) { "FlowNode missing id" }
!pattern.matches(nodeId)
}
.map { node ->
ValidationViolation(
ruleId = id,
severity = severity,
elementId = node.id,
processId = context.model.processId,
message = "Element ID '${node.id}' does not match format type_DescriptionInCamelCase",
)
}
}
}
For hybrid rules, the class comment calls out the semantic half:
/**
* service-task-topic (hybrid — deterministic half only)
* Category: technical-configuration
*
* This rule covers the deterministic shape check. The semantic half
* ('<elementIdWithoutPrefix>' actually matches the element ID minus
* 'serviceTask_') is enforced by /validate-bpmn-style.
*/
class ServiceTaskTopicRule : BpmnValidationRule { /* ... */ }
Aggregator:
object BpmnStyleGuideRules {
@JvmField val ELEMENT_ID_FORMAT = ElementIdFormatRule()
@JvmField val SERVICE_TASK_TOPIC = ServiceTaskTopicRule()
// …
@JvmStatic
fun all(): List<BpmnValidationRule> = listOf(
ELEMENT_ID_FORMAT,
SERVICE_TASK_TOPIC,
// …
)
}
Before asking for an output location, see what the project already has:
**/src/test/kotlin/**/architecture/bpmn/**/*.kt, plus a broader **/src/test/kotlin/**/*Rule.kt to catch alternative layouts.: BpmnValidationRule (class declarations) and for each slug from the style guide (as the override val id = "<slug>" literal).BpmnStyleGuideRules.kt file already exists at the expected path, read it. Show the user the rules that are already implemented and ask whether to overwrite, merge (add the new rules and keep existing ones that aren't in the style guide), or abort.id exist in different files or under different class names, list them and ask the user how to resolve: replace, skip (don't regenerate this rule), or write alongside (let the user deduplicate manually).Default to src/test/kotlin/<package>/architecture/bpmn/BpmnStyleGuideRules.kt inside the module that holds bpmn-to-code-testing (from Step 0). <package> should match the project's test package convention. If Step 4 found an existing aggregator or rule files, suggest the same location. Confirm or let the user override.
Create architecture/bpmn/ if it doesn't exist.
Write the file.
Run ./gradlew compileKotlin (or the module's test-compile task).
If compilation fails, fix and retry.
Show how to integrate:
BpmnValidator
.fromClasspath("bpmn/")
.engine(ProcessEngine.CAMUNDA_7)
.withRules(BpmnRules.all() + BpmnStyleGuideRules.all())
.validate()
.assertNoErrors()
Remind the user that LLM-only rules and the semantic half of hybrid rules still need /validate-bpmn-style — the test suite alone won't cover them.
npx claudepluginhub miragon/bpmn-to-code --plugin bpmn-to-codeCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.