Camunda 7 to 8 Migration
Migrate a Camunda 7 project to Camunda 8. A project holds two independent kinds of assets:
- Code — Java/Spring glue and client code, config, tests. Migrated with OpenRewrite recipes
(deterministic) plus AI cleanup.
- Models — BPMN/DMN diagrams in the
camunda: namespace. Migrated with the Diagram Converter
(deterministic) or agentically.
Every instruction here is mandatory. "Never" means MUST NOT. A preference is marked (SHOULD) and an
option is marked (MAY).
Step 0: Model preflight
This skill needs complex, multi-file reasoning. Before the scan, read the active model identifier or
capability metadata that the host exposes. Never infer it and never read undocumented variables.
Recommended examples: claude-sonnet-*, claude-opus-*, gpt-5.6-luna, gpt-5.6-terra,
gpt-5.6-sol. Caution examples: gpt-5-mini, gpt-5.4-mini, gemini-3.7-flash. These are routing
examples, not a benchmark and not a ranking. Prefer host capability metadata. (SHOULD) Treat an unknown identifier as unverified.
If the model is lightweight (mini, small, lite, flash, haiku, and similar) or unverified, then warn
the user and ask through AskUserQuestion, or the host equivalent:
- Switch to a model built for complex reasoning (recommended) — explain the host model selector,
wait for confirmation, then read the host model metadata again.
- Continue — use deterministic approaches and ask for extra human review.
Where the host permits a model change, repeat this check before AI-only migration, an agentic
rewrite, and AI cleanup. Once the user confirms the project root, record the preflight result, the
model identifier or its unverified status, and any decision to continue on a caution or unverified
model in MIGRATION_REPORT.md.
Entry Criteria
- The project declares Camunda 7 (camunda-bpm) dependencies in Maven or Gradle.
- The project contains one or more of: JavaDelegate implementations, ExternalTaskWorkers,
ProcessEngine/RuntimeService client code, execution/task listeners, BPMN/DMN files with the
camunda: namespace, or application config with camunda.* keys.
- The target is Camunda 8 version 8.8, 8.9, or 8.10.
- Where OpenRewrite is selected (recommended), Maven or Gradle is available.
- Where the Diagram Converter CLI is selected, Java 21+ is on
PATH or in a user-supplied JDK home.
Alternatives exist when it is not.
Implementation Steps
Step 1: Gather Inputs
See references/interview-questions.md for the question set and the batching rules.
- Detect the project root, the build tool (
pom.xml, or build.gradle / build.gradle.kts), and
the model files (*.bpmn, *.bpmn20.xml, *.dmn, *.dmn11.xml).
- Ask Question 1 (project location) through AskUserQuestion.
- If the confirmed root differs from the candidate, then scan the confirmed root again.
- Ask Questions 2 and 3 (target version, scope) together.
- Ask Questions 4 to 6 (code approach, model approach, build tool) where they apply.
- When the user accepts the defaults, continue without further questions.
Shared rules
These rules apply to every later step.
Assets and tools
- Route each asset kind to the selected Part A or Part B approach.
- For code, use the selected Part A approach: OpenRewrite plus AI, AI only, or assessment only.
- For models, use the Diagram Converter in M1, M3, or E1, or agentic editing in M2.
- Only M2 edits BPMN/DMN agentically, and only on a converted copy.
- Never hand-edit BPMN or DMN in the code flow.
- Use project-local models first. While local models exist, never offer or request Camunda 7 engine
access.
- Prefer the deterministic path: OpenRewrite plus AI over AI-only for code, the CLI over an agentic
rewrite for models. (SHOULD)
- Use invocations that suit the current platform. Never assume one shell dialect.
Safety
- Before the first change, check for uncommitted changes. If the working tree is dirty, then ask the
user to commit or stash.
- Never commit without an explicit user request.
- Write each converted model to a
converted-c8-* copy. Leave every original file unchanged.
- Where the target is a separate location, such as a sibling Camunda 8 project, treat the Camunda 7
project as read-only and copy the assets across.
- Before any edit, load the pattern catalog. See
references/pattern-catalog-sources.md.
- Never guess an API mapping or an XML mapping.
- Never offer a feature from a version above the selected target.
- Before each Java-dependent phase, run
java -version on PATH. If that major version is missing
or incompatible, then ask for an alternate JDK home and check it before continuing.
- Scope that JDK home to one phase.
- Apply a mapping unasked only when it is an unambiguous 1:1 mapping.
- Ask before changing a high-complexity file or an edge case.
Minimal, faithful change
- Never refactor, rename, or improve anything beyond the migration.
- Before rewriting code, check whether a tool already transformed it.
- Carry package names, class names, file and folder layout, resource paths, startup behavior, and the
dependency footprint across unchanged wherever a Camunda 8 equivalent exists.
- Rename or delete only what has no Camunda 8 equivalent, and record why in
MIGRATION_REPORT.md.
- Many Camunda 7 patterns exist only because of a Camunda 7 limitation: flat form binding, no
computed display value, the in-process engine API. Before replicating such a pattern or adding a
worker, check whether Camunda 8 no longer has the limitation.
- When a finding reports that Zeebe now supports a capability natively, run the same check on the
Camunda 7 workaround code. See
references/composing-code-and-models.md.
Findings and report
- A finished conversion is not a finished migration. Every WARNING, TASK, and REVIEW finding needs
human follow-up.
- An INFO finding is informational until a later cross-check identifies work.
- Converter annotations are temporary review metadata. Once the verdict table is complete, strip
conversion:* elements and attributes from the converted copies with namespace-aware XML tooling.
- Keep
MIGRATION_REPORT.md in the confirmed project root.
- Keep
MIGRATION_REPORT.md current.
- Use
MIGRATION_REPORT.md as the single source of truth for inventories, decisions, open items,
phase status, incompatibilities, and validation results.
- Never scatter this record across separate notes.
- Keep an open-items section in
MIGRATION_REPORT.md for each design question the migration cannot
answer.
- Name the call site in each open item.
- State the question in each open item.
- Set each open item to status
open or resolved.
- Create an open item for every migrated query against secondary storage, regardless of the running
model.
- See
references/code-transform-checklist.md for the mandatory triggers and the wording.
Forms
A form-free owner is a user task or a process-level none start event that carries no form metadata
at all.
- Build the form inventory from the original BPMN source in Step 2, never from converter findings.
Treat findings as corroboration only.
- If a finding and the source disagree, then report the disagreement. Never pick one side silently.
- Generated Task Forms are an agentic follow-up, not a Diagram Converter feature. Keep the converter's
form-data manual finding, generate standard .form resources from the exact original BPMN, and
follow references/form-migration.md for every decision and every link.
- Copying a reference does not migrate a referenced form. Embedded HTML/JavaScript keys, external or
custom application keys, Camunda Form references, and form-free owners each need their own
decision. See
references/form-reference-migration.md.
- Offer to rebuild a form as a Camunda 8 form, and generate one only on an explicit user request. A
rebuilt form reproduces the data contract, never the Camunda 7 user interface.
- Never accept, link, or deploy a generated form before the user reviews it. Ask about every semantic
gap and every unsupported construct, and never invent a replacement.
Step 2: Assessment (always runs)
Scan the project and produce the inventories that the chosen scope needs.
Code Inventory
Classify every Camunda 7 related Java file and config file into a table with the columns File, Type,
Complexity, Notes. See references/code-transform-checklist.md for the detection hints and the type
classifications.
Record the original Java source baseline used for migration with the Code Inventory. Record each
class by its fully qualified class name, including its package and class name. Include every domain
or service class that could receive or delegate a @JobWorker, including classes without Camunda
APIs.
Model Inventory
Glob for the model files. Record each one in a table with the columns File, Type, Uses camunda: ns,
Notes.
Then parse every original BPMN with a namespace-aware parser and inventory all three Camunda 7 form
surfaces:
| Surface |
Record |
Generated Task Forms (camunda:formData, camunda:formProperty) |
source file, process id, owning user task or start event, field count, business-key field, custom types and validators, initial status |
Referenced forms (camunda:formKey, camunda:formRef) |
the classification, and whether the referenced HTML or .form file exists in the project |
| Generic Task Forms (no form metadata at all) |
every form-free owner affected |
See references/form-reference-migration.md for the classification rules and the full inventory
columns.
If the model inventory is empty and the user selected model migration, then record that no local
model was found and that E1 was offered.
Summary
Present the code file count, the model file count, the overall complexity, whether OpenRewrite would
help, the blockers that need a manual decision, and the Step 0 preflight result including any user
acknowledgment. State that running instances, history, and audit data are out of scope, and point the
user to the Data Migrator.
Write the assessment to MIGRATION_REPORT.md. Ask the user to confirm before Step 3, using
AskUserQuestion.
Step 3: Execute Migration
Run Part A when the scope includes code. Run Part B when the scope includes models. For Code +
models, see references/composing-code-and-models.md.
Part A - Code Migration
Apply the Transform checklist from references/code-transform-checklist.md with the approach chosen
in Question 4. See references/code-migration-approaches.md for all three.
- A. OpenRewrite + AI (recommended) — run the recipes, then clean up what they left.
- B. AI only — work checklist items 1 to 8 in order, confirming each one.
- C. Assessment only — report with effort estimates, no code changes.
Part B - Model Migration
Convert BPMN/DMN from the camunda: namespace to zeebe: with the approach chosen in Question 5.
See references/model-migration-approaches.md for all four.
- M1. Diagram Converter CLI + AI (recommended) — download and run the CLI, then handle the
findings.
- M2. Agentic AI — rewrite the XML directly, without the CLI.
- M3. Online Converter — the user uploads the diagrams at the hosted service.
- E1. Camunda 7 engine source — fetch the definitions from the Camunda 7 REST API when no local
model exists.
For every approach, once each original BPMN is paired with its converted copy, run
references/form-migration.md for the Generated Task Forms, then
references/form-reference-migration.md for the referenced forms and the form-free owners.
Step 4: Validation (always runs)
Each item below is a check to run and a condition that must hold at exit. Record every result in
MIGRATION_REPORT.md.
Code checks, when code was migrated
- Compile — run
mvn compile or the Gradle compile task. Fix every error.
- Camunda 7 dependencies — no dependency with groupId
org.camunda.bpm remains in the build files. No dependency with a groupId that starts with org.camunda.bpm. remains either.
- Camunda 7 imports — search
org.camunda.bpm. No import remains. Each one is a missed
migration.
- Migration TODOs — search for
// TODO comments that OpenRewrite inserted or that mark
migration work. Review each matching TODO and resolve or record it.
- Legacy Camunda 8 client — search
ZeebeClient and zeebe-client-java. No reference remains.
Use CamundaClient.
- Business keys — search
businessKey. Each use maps per the pattern catalog: businessId on
8.9+, tags on 8.8. A key the process mutates stays a businessKey process variable.
- Configuration —
camunda.client.* keys replace the camunda.* keys in
application.properties or .yaml.
- Tests — run
mvn test or the Gradle test task. Every test passes, or each failure is
documented with an explanation.
- Eventually-consistent queries — search for every C8 search-request factory method listed in
references/code-transform-checklist.md, not only the SearchRequest type name. Every migrated
search call site has a matching open item in the MIGRATION_REPORT.md open-items section. A
missing entry fails the check. See the mandatory open items in
references/code-transform-checklist.md.
- Worker adapters — compare every
@JobWorker declaration's fully qualified declaring class
name with the original Java source baseline recorded in Step 2. Flag the declaration when its
class appears in that baseline, even when the class name ends with Worker. Accept it only
when the class is absent from the baseline, is a new *Worker adapter component, and delegates
to the baseline bean. Record each flagged declaration and its replacement adapter in
MIGRATION_REPORT.md. A migrated Spring bean method must never receive @JobWorker directly.
Check these pitfalls as well:
- Naming swap: Camunda 7
processDefinitionKey (a string key) becomes Camunda 8 bpmnProcessId, and
Camunda 7 processDefinitionId (a UUID) becomes Camunda 8 processDefinitionKey. Decision
definitions swap the same way.
- Camunda 7
processInstanceId is a String. Camunda 8 processInstanceKey is a Long. Update declarations and call sites, not only the names.
- Variables are plain JSON and the
TypedValue API is gone, so every VariableMap use changes.
- Batch operations exist since 8.8. Only a custom batch handler needs a manual design.
Model checks, when models were migrated
After every manual BPMN edit, lint the converted copy with the Camunda compatibility ruleset for the
target version. See the linting section in references/model-migration-approaches.md.
- A
converted-c8-* file exists for every in-scope diagram, unless the run is analyze-only.
- Every original file is intact and was never overwritten.
- Treat every resource directory that the build configures for inclusion in a Maven or Gradle
application artifact as a packaged resource directory. Include
src/main/resources when it
exists. No findings report named analysis-results.<ext> or analysis-results (n).<ext> remains
under a packaged resource directory, where n is a positive integer and <ext> is .csv,
.json, .md, or .xlsx. Keep findings reports under .camunda-migration/reports/ only when
the build does not package that directory. Otherwise, use another explicitly non-packaged
directory.
- Every WARNING, TASK, and REVIEW finding is fixed, or classified in the per-category verdict table
with its category, count, cross-referenced code artifact, and verdict. See
references/model-migration-approaches.md step 5d. A flat "fixed or recorded" note is not enough.
- Every source Generated Task Form is
accepted, blocked, or declined, including a
form-property-only definition. None is silently omitted.
- Every accepted form is a standard Camunda 8
.form.
- Every accepted form parses.
- Where a target-compatible official schema exists, the skill validates every accepted form with it.
- Where target-compatible form-js tooling exists, the skill imports or renders every accepted form
with it.
- Every accepted form has a matching
zeebe:formDefinition.
- The skill deploys every accepted form with its BPMN.
- No draft, blocked, or declined form is linked or deployed. Every semantic gap and every user
decision is recorded.
- Every referenced form and every form-free owner has a recorded per-category decision and a final
status of
kept, relinked, accepted, declined, deferred, or blocked. The in-progress
statuses pending and draft must not remain. A deferred or blocked item stays open follow-up
work. A kept external reference is never reported as a completed migration, and no category is
closed as no action because the converter copied a reference.
- Every relinked or rebuilt form is referenced by
zeebe:formDefinition@formId with a recorded
binding decision: bindingType written for deployment and versionTag, or latest left
deliberately to the Camunda 8 default. The copied Camunda 7 externalReference or formKey is
gone from that element.
- Once the verdict table is complete, the converted copies hold no
conversion:* node, no
conversion:* attribute, no unused Camunda 7 namespace declaration, and no leftover BPMN
definitions-level XPath expressionLanguage attribute.
- When the model uses M2, inspect every
zeebe:taskDefinition/@type. Derive the expected type
from the original camunda:delegateExpression, camunda:expression, camunda:class, or
camunda:topic attribute using the binding rules in
references/model-migration-approaches.md. If the emitted type differs, require a confirmed
decision-log entry in MIGRATION_REPORT.md with the source file and element, original
implementation, emitted type, and rationale. Treat a mismatch without that entry as a
validation failure.
Summary
Present a validation summary that states the status of compilation, remaining Camunda 7 imports,
remaining migration TODOs, businessKey uses, the open items, tests, converted models, and the
findings that still need follow-up. Record it in MIGRATION_REPORT.md.
Step 5: AI Follow-up (offer after validation)
If any migration TODO, finding, compilation issue, deletion candidate, or unresolved item remains, then offer
to resolve it:
I found [N] remaining items that need follow-up. Would you like me to take care of them?
Use AskUserQuestion with these options:
- Yes, fix what you can (recommended) — resolve the unambiguous items, and propose each one for
review.
- Show me the list first — present the full list grouped by type, then ask which items to fix.
- No, I will handle the rest manually — stop, and record the remaining items in
MIGRATION_REPORT.md.
Action 1: fix findings and migration TODOs
For model findings, work from the Step 4 verdict table. Never present model findings as one
undifferentiated list.
| Verdict |
Action |
| needs fix |
Resolve one category at a time, using that category's cross-check guidance. |
| needs review |
Collect the pending user decision through AskUserQuestion before any fix. |
| no action |
Do not offer the category. |
- Apply an unambiguous fix directly, using the pattern catalog.
- Propose an ambiguous fix through AskUserQuestion. Skip whatever the user declines.
- Handle
form-data and source-detected formProperty through references/form-migration.md:
generate the drafts deterministically, and link only an accepted form.
- Handle the form-reference categories through
references/form-reference-migration.md: present the
inventory, and take one decision per integration group inside each category, grouping only owners
that share an integration.
- After each batch, ask whether to commit.
- For a model-finding batch, update the verdict table in
MIGRATION_REPORT.md.
Action 2: delete now-redundant code
The model/code cross-check flags Camunda 7 workaround code as a deletion candidate when a finding
reports that Zeebe now provides the capability natively. See "Now-redundant workaround code" in
references/composing-code-and-models.md.
Deleting code is never unambiguous. Even under "Yes, fix what you can", present every deletion
candidate through AskUserQuestion with its reasoning: the triggering finding, what the code did, and
why it is now redundant. Delete only on an explicit confirmation. Record the confirmed deletions and
the declined candidates in MIGRATION_REPORT.md.
Exit Criteria
The migration run may exit when every pass condition in Step 4 holds and MIGRATION_REPORT.md holds
the complete inventories, the decisions, the open items, and the validation results.
The skill reports a complete migration only when no unresolved migration TODO, finding, compilation
issue, or deletion candidate remains and no item has deferred or blocked status.
An open item is a team decision, so an open status does not block completion, but the summary
always lists every open item.
Otherwise, the skill reports the migration as incomplete and records the follow-up work.
1---2name: migrate-c7-to-c8-code3description: Migrates Camunda 7 / camunda-bpm projects to Camunda 8. Handles Java/Spring code (JavaDelegates, ExternalTaskWorkers, ProcessEngine/RuntimeService client code, execution/task listeners, application.properties/application.yaml with camunda.* keys) and BPMN/DMN models (diagrams with the camunda: namespace). Use for code migration, model migration, or both.4license: Camunda License 1.05---67# Camunda 7 to 8 Migration89Migrate a Camunda 7 project to Camunda 8. A project holds two independent kinds of assets:1011- **Code** — Java/Spring glue and client code, config, tests. Migrated with OpenRewrite recipes12 (deterministic) plus AI cleanup.13- **Models** — BPMN/DMN diagrams in the `camunda:` namespace. Migrated with the Diagram Converter14 (deterministic) or agentically.1516Every instruction here is mandatory. "Never" means MUST NOT. A preference is marked (SHOULD) and an17option is marked (MAY).1819## Step 0: Model preflight2021This skill needs complex, multi-file reasoning. Before the scan, read the active model identifier or22capability metadata that the host exposes. Never infer it and never read undocumented variables.23Recommended examples: `claude-sonnet-*`, `claude-opus-*`, `gpt-5.6-luna`, `gpt-5.6-terra`,24`gpt-5.6-sol`. Caution examples: `gpt-5-mini`, `gpt-5.4-mini`, `gemini-3.7-flash`. These are routing25examples, not a benchmark and not a ranking. Prefer host capability metadata. (SHOULD) Treat an unknown identifier as unverified.2627If the model is lightweight (mini, small, lite, flash, haiku, and similar) or unverified, then warn28the user and ask through AskUserQuestion, or the host equivalent:2930- **Switch to a model built for complex reasoning (recommended)** — explain the host model selector,31 wait for confirmation, then read the host model metadata again.32- **Continue** — use deterministic approaches and ask for extra human review.3334Where the host permits a model change, repeat this check before AI-only migration, an agentic35rewrite, and AI cleanup. Once the user confirms the project root, record the preflight result, the36model identifier or its unverified status, and any decision to continue on a caution or unverified37model in `MIGRATION_REPORT.md`.3839## Entry Criteria40411. The project declares Camunda 7 (camunda-bpm) dependencies in Maven or Gradle.422. The project contains one or more of: JavaDelegate implementations, ExternalTaskWorkers,43 ProcessEngine/RuntimeService client code, execution/task listeners, BPMN/DMN files with the44 `camunda:` namespace, or application config with `camunda.*` keys.453. The target is Camunda 8 version 8.8, 8.9, or 8.10.464. Where OpenRewrite is selected (recommended), Maven or Gradle is available.475. Where the Diagram Converter CLI is selected, Java 21+ is on `PATH` or in a user-supplied JDK home.48 Alternatives exist when it is not.4950## Implementation Steps5152### Step 1: Gather Inputs5354See `references/interview-questions.md` for the question set and the batching rules.55561. Detect the project root, the build tool (`pom.xml`, or `build.gradle` / `build.gradle.kts`), and57 the model files (`*.bpmn`, `*.bpmn20.xml`, `*.dmn`, `*.dmn11.xml`).582. Ask Question 1 (project location) through AskUserQuestion.593. If the confirmed root differs from the candidate, then scan the confirmed root again.604. Ask Questions 2 and 3 (target version, scope) together.615. Ask Questions 4 to 6 (code approach, model approach, build tool) where they apply.626. When the user accepts the defaults, continue without further questions.6364#### Shared rules6566These rules apply to every later step.6768**Assets and tools**6970- Route each asset kind to the selected Part A or Part B approach.71- For code, use the selected Part A approach: OpenRewrite plus AI, AI only, or assessment only.72- For models, use the Diagram Converter in M1, M3, or E1, or agentic editing in M2.73- Only M2 edits BPMN/DMN agentically, and only on a converted copy.74- Never hand-edit BPMN or DMN in the code flow.75- Use project-local models first. While local models exist, never offer or request Camunda 7 engine76 access.77- Prefer the deterministic path: OpenRewrite plus AI over AI-only for code, the CLI over an agentic78 rewrite for models. (SHOULD)79- Use invocations that suit the current platform. Never assume one shell dialect.8081**Safety**8283- Before the first change, check for uncommitted changes. If the working tree is dirty, then ask the84 user to commit or stash.85- Never commit without an explicit user request.86- Write each converted model to a `converted-c8-*` copy. Leave every original file unchanged.87- Where the target is a separate location, such as a sibling Camunda 8 project, treat the Camunda 788 project as read-only and copy the assets across.89- Before any edit, load the pattern catalog. See `references/pattern-catalog-sources.md`.90- Never guess an API mapping or an XML mapping.91- Never offer a feature from a version above the selected target.92- Before each Java-dependent phase, run `java -version` on `PATH`. If that major version is missing93 or incompatible, then ask for an alternate JDK home and check it before continuing.94- Scope that JDK home to one phase.95- Apply a mapping unasked only when it is an unambiguous 1:1 mapping.96- Ask before changing a high-complexity file or an edge case.9798**Minimal, faithful change**99100- Never refactor, rename, or improve anything beyond the migration.101- Before rewriting code, check whether a tool already transformed it.102- Carry package names, class names, file and folder layout, resource paths, startup behavior, and the103 dependency footprint across unchanged wherever a Camunda 8 equivalent exists.104- Rename or delete only what has no Camunda 8 equivalent, and record why in `MIGRATION_REPORT.md`.105- Many Camunda 7 patterns exist only because of a Camunda 7 limitation: flat form binding, no106 computed display value, the in-process engine API. Before replicating such a pattern or adding a107 worker, check whether Camunda 8 no longer has the limitation.108- When a finding reports that Zeebe now supports a capability natively, run the same check on the109 Camunda 7 workaround code. See `references/composing-code-and-models.md`.110111**Findings and report**112113- A finished conversion is not a finished migration. Every WARNING, TASK, and REVIEW finding needs114 human follow-up.115- An INFO finding is informational until a later cross-check identifies work.116- Converter annotations are temporary review metadata. Once the verdict table is complete, strip117 `conversion:*` elements and attributes from the converted copies with namespace-aware XML tooling.118- Keep `MIGRATION_REPORT.md` in the confirmed project root.119- Keep `MIGRATION_REPORT.md` current.120- Use `MIGRATION_REPORT.md` as the single source of truth for inventories, decisions, open items,121 phase status, incompatibilities, and validation results.122- Never scatter this record across separate notes.123- Keep an open-items section in `MIGRATION_REPORT.md` for each design question the migration cannot124 answer.125- Name the call site in each open item.126- State the question in each open item.127- Set each open item to status `open` or `resolved`.128- Create an open item for every migrated query against secondary storage, regardless of the running129 model.130- See `references/code-transform-checklist.md` for the mandatory triggers and the wording.131132**Forms**133134A **form-free owner** is a user task or a process-level none start event that carries no form metadata135at all.136137- Build the form inventory from the original BPMN source in Step 2, never from converter findings.138 Treat findings as corroboration only.139- If a finding and the source disagree, then report the disagreement. Never pick one side silently.140- Generated Task Forms are an agentic follow-up, not a Diagram Converter feature. Keep the converter's141 `form-data` manual finding, generate standard `.form` resources from the exact original BPMN, and142 follow `references/form-migration.md` for every decision and every link.143- Copying a reference does not migrate a referenced form. Embedded HTML/JavaScript keys, external or144 custom application keys, Camunda Form references, and form-free owners each need their own145 decision. See `references/form-reference-migration.md`.146- Offer to rebuild a form as a Camunda 8 form, and generate one only on an explicit user request. A147 rebuilt form reproduces the data contract, never the Camunda 7 user interface.148- Never accept, link, or deploy a generated form before the user reviews it. Ask about every semantic149 gap and every unsupported construct, and never invent a replacement.150151### Step 2: Assessment (always runs)152153Scan the project and produce the inventories that the chosen scope needs.154155#### Code Inventory156157Classify every Camunda 7 related Java file and config file into a table with the columns File, Type,158Complexity, Notes. See `references/code-transform-checklist.md` for the detection hints and the type159classifications.160161Record the original Java source baseline used for migration with the Code Inventory. Record each162class by its fully qualified class name, including its package and class name. Include every domain163or service class that could receive or delegate a `@JobWorker`, including classes without Camunda164APIs.165166#### Model Inventory167168Glob for the model files. Record each one in a table with the columns File, Type, Uses `camunda:` ns,169Notes.170171Then parse every original BPMN with a namespace-aware parser and inventory all three Camunda 7 form172surfaces:173174| Surface | Record |175|---|---|176| Generated Task Forms (`camunda:formData`, `camunda:formProperty`) | source file, process id, owning user task or start event, field count, business-key field, custom types and validators, initial status |177| Referenced forms (`camunda:formKey`, `camunda:formRef`) | the classification, and whether the referenced HTML or `.form` file exists in the project |178| Generic Task Forms (no form metadata at all) | every form-free owner affected |179180See `references/form-reference-migration.md` for the classification rules and the full inventory181columns.182183If the model inventory is empty and the user selected model migration, then record that no local184model was found and that E1 was offered.185186#### Summary187188Present the code file count, the model file count, the overall complexity, whether OpenRewrite would189help, the blockers that need a manual decision, and the Step 0 preflight result including any user190acknowledgment. State that running instances, history, and audit data are out of scope, and point the191user to the Data Migrator.192193Write the assessment to `MIGRATION_REPORT.md`. Ask the user to confirm before Step 3, using194AskUserQuestion.195196### Step 3: Execute Migration197198Run Part A when the scope includes code. Run Part B when the scope includes models. For Code +199models, see `references/composing-code-and-models.md`.200201#### Part A - Code Migration202203Apply the Transform checklist from `references/code-transform-checklist.md` with the approach chosen204in Question 4. See `references/code-migration-approaches.md` for all three.205206- **A. OpenRewrite + AI** (recommended) — run the recipes, then clean up what they left.207- **B. AI only** — work checklist items 1 to 8 in order, confirming each one.208- **C. Assessment only** — report with effort estimates, no code changes.209210#### Part B - Model Migration211212Convert BPMN/DMN from the `camunda:` namespace to `zeebe:` with the approach chosen in Question 5.213See `references/model-migration-approaches.md` for all four.214215- **M1. Diagram Converter CLI + AI** (recommended) — download and run the CLI, then handle the216 findings.217- **M2. Agentic AI** — rewrite the XML directly, without the CLI.218- **M3. Online Converter** — the user uploads the diagrams at the hosted service.219- **E1. Camunda 7 engine source** — fetch the definitions from the Camunda 7 REST API when no local220 model exists.221222For every approach, once each original BPMN is paired with its converted copy, run223`references/form-migration.md` for the Generated Task Forms, then224`references/form-reference-migration.md` for the referenced forms and the form-free owners.225### Step 4: Validation (always runs)226227Each item below is a check to run and a condition that must hold at exit. Record every result in228`MIGRATION_REPORT.md`.229230#### Code checks, when code was migrated2312321. **Compile** — run `mvn compile` or the Gradle compile task. Fix every error.2332. **Camunda 7 dependencies** — no dependency with groupId `org.camunda.bpm` remains in the build files. No dependency with a groupId that starts with `org.camunda.bpm.` remains either.2343. **Camunda 7 imports** — search `org.camunda.bpm`. No import remains. Each one is a missed235 migration.2364. **Migration TODOs** — search for `// TODO` comments that OpenRewrite inserted or that mark237 migration work. Review each matching TODO and resolve or record it.2385. **Legacy Camunda 8 client** — search `ZeebeClient` and `zeebe-client-java`. No reference remains.239 Use `CamundaClient`.2406. **Business keys** — search `businessKey`. Each use maps per the pattern catalog: businessId on241 8.9+, tags on 8.8. A key the process mutates stays a `businessKey` process variable.2427. **Configuration** — `camunda.client.*` keys replace the `camunda.*` keys in243 `application.properties` or `.yaml`.2448. **Tests** — run `mvn test` or the Gradle test task. Every test passes, or each failure is245 documented with an explanation.2469. **Eventually-consistent queries** — search for every C8 search-request factory method listed in247 `references/code-transform-checklist.md`, not only the `SearchRequest` type name. Every migrated248 search call site has a matching open item in the `MIGRATION_REPORT.md` open-items section. A249 missing entry fails the check. See the mandatory open items in250 `references/code-transform-checklist.md`.25110. **Worker adapters** — compare every `@JobWorker` declaration's fully qualified declaring class252 name with the original Java source baseline recorded in Step 2. Flag the declaration when its253 class appears in that baseline, even when the class name ends with `Worker`. Accept it only254 when the class is absent from the baseline, is a new `*Worker` adapter component, and delegates255 to the baseline bean. Record each flagged declaration and its replacement adapter in256 `MIGRATION_REPORT.md`. A migrated Spring bean method must never receive `@JobWorker` directly.257258Check these pitfalls as well:259260- Naming swap: Camunda 7 `processDefinitionKey` (a string key) becomes Camunda 8 `bpmnProcessId`, and261 Camunda 7 `processDefinitionId` (a UUID) becomes Camunda 8 `processDefinitionKey`. Decision262 definitions swap the same way.263- Camunda 7 `processInstanceId` is a `String`. Camunda 8 `processInstanceKey` is a `Long`. Update declarations and call sites, not only the names.264- Variables are plain JSON and the `TypedValue` API is gone, so every `VariableMap` use changes.265- Batch operations exist since 8.8. Only a custom batch handler needs a manual design.266267#### Model checks, when models were migrated268269After every manual BPMN edit, lint the converted copy with the Camunda compatibility ruleset for the270target version. See the linting section in `references/model-migration-approaches.md`.2712721. A `converted-c8-*` file exists for every in-scope diagram, unless the run is analyze-only.2732. Every original file is intact and was never overwritten.2743. Treat every resource directory that the build configures for inclusion in a Maven or Gradle275 application artifact as a packaged resource directory. Include `src/main/resources` when it276 exists. No findings report named `analysis-results.<ext>` or `analysis-results (n).<ext>` remains277 under a packaged resource directory, where `n` is a positive integer and `<ext>` is `.csv`,278 `.json`, `.md`, or `.xlsx`. Keep findings reports under `.camunda-migration/reports/` only when279 the build does not package that directory. Otherwise, use another explicitly non-packaged280 directory.2814. Every WARNING, TASK, and REVIEW finding is fixed, or classified in the per-category verdict table282 with its category, count, cross-referenced code artifact, and verdict. See283 `references/model-migration-approaches.md` step 5d. A flat "fixed or recorded" note is not enough.2845. Every source Generated Task Form is `accepted`, `blocked`, or `declined`, including a285 form-property-only definition. None is silently omitted.2866. Every accepted form is a standard Camunda 8 `.form`.2877. Every accepted form parses.2888. Where a target-compatible official schema exists, the skill validates every accepted form with it.2899. Where target-compatible form-js tooling exists, the skill imports or renders every accepted form290 with it.29110. Every accepted form has a matching `zeebe:formDefinition`.29211. The skill deploys every accepted form with its BPMN.29312. No draft, blocked, or declined form is linked or deployed. Every semantic gap and every user294 decision is recorded.29513. Every referenced form and every form-free owner has a recorded per-category decision and a final296 status of `kept`, `relinked`, `accepted`, `declined`, `deferred`, or `blocked`. The in-progress297 statuses `pending` and `draft` must not remain. A `deferred` or `blocked` item stays open follow-up298 work. A kept external reference is never reported as a completed migration, and no category is299 closed as **no action** because the converter copied a reference.30014. Every relinked or rebuilt form is referenced by `zeebe:formDefinition@formId` with a recorded301 binding decision: `bindingType` written for `deployment` and `versionTag`, or `latest` left302 deliberately to the Camunda 8 default. The copied Camunda 7 `externalReference` or `formKey` is303 gone from that element.30415. Once the verdict table is complete, the converted copies hold no `conversion:*` node, no305 `conversion:*` attribute, no unused Camunda 7 namespace declaration, and no leftover BPMN306 definitions-level XPath `expressionLanguage` attribute.30716. When the model uses M2, inspect every `zeebe:taskDefinition/@type`. Derive the expected type308 from the original `camunda:delegateExpression`, `camunda:expression`, `camunda:class`, or309 `camunda:topic` attribute using the binding rules in310 `references/model-migration-approaches.md`. If the emitted type differs, require a confirmed311 decision-log entry in `MIGRATION_REPORT.md` with the source file and element, original312 implementation, emitted type, and rationale. Treat a mismatch without that entry as a313 validation failure.314315#### Summary316317Present a validation summary that states the status of compilation, remaining Camunda 7 imports,318remaining migration TODOs, `businessKey` uses, the open items, tests, converted models, and the319findings that still need follow-up. Record it in `MIGRATION_REPORT.md`.320321### Step 5: AI Follow-up (offer after validation)322323If any migration TODO, finding, compilation issue, deletion candidate, or unresolved item remains, then offer324to resolve it:325326> I found [N] remaining items that need follow-up. Would you like me to take care of them?327328Use AskUserQuestion with these options:329330- **Yes, fix what you can (recommended)** — resolve the unambiguous items, and propose each one for331 review.332- **Show me the list first** — present the full list grouped by type, then ask which items to fix.333- **No, I will handle the rest manually** — stop, and record the remaining items in334 `MIGRATION_REPORT.md`.335336#### Action 1: fix findings and migration TODOs337338For model findings, work from the Step 4 verdict table. Never present model findings as one339undifferentiated list.340341| Verdict | Action |342|---|---|343| **needs fix** | Resolve one category at a time, using that category's cross-check guidance. |344| **needs review** | Collect the pending user decision through AskUserQuestion before any fix. |345| **no action** | Do not offer the category. |346347- Apply an unambiguous fix directly, using the pattern catalog.348- Propose an ambiguous fix through AskUserQuestion. Skip whatever the user declines.349- Handle `form-data` and source-detected `formProperty` through `references/form-migration.md`:350 generate the drafts deterministically, and link only an accepted form.351- Handle the form-reference categories through `references/form-reference-migration.md`: present the352 inventory, and take one decision per integration group inside each category, grouping only owners353 that share an integration.354- After each batch, ask whether to commit.355- For a model-finding batch, update the verdict table in `MIGRATION_REPORT.md`.356357#### Action 2: delete now-redundant code358359The model/code cross-check flags Camunda 7 workaround code as a deletion candidate when a finding360reports that Zeebe now provides the capability natively. See "Now-redundant workaround code" in361`references/composing-code-and-models.md`.362363Deleting code is never unambiguous. Even under "Yes, fix what you can", present every deletion364candidate through AskUserQuestion with its reasoning: the triggering finding, what the code did, and365why it is now redundant. Delete only on an explicit confirmation. Record the confirmed deletions and366the declined candidates in `MIGRATION_REPORT.md`.367368## Exit Criteria369370The migration run may exit when every pass condition in Step 4 holds and `MIGRATION_REPORT.md` holds371the complete inventories, the decisions, the open items, and the validation results.372The skill reports a complete migration only when no unresolved migration TODO, finding, compilation373issue, or deletion candidate remains and no item has `deferred` or `blocked` status.374An open item is a team decision, so an `open` status does not block completion, but the summary375always lists every open item.376Otherwise, the skill reports the migration as incomplete and records the follow-up work.