Skip to main content

neo-to-cf-migration-orchestrator

Invoke this skill to orchestrate complete Neo to Cloud Foundry migration. Analyzes the Neo app, creates a migration plan, and dispatches each migration scenario (Jakarta, SDK, auth, persistence, destinations, etc.) to a separate subagent so the orchestrator's context stays lean across the full 5–14 step pipeline. Use when user says 'migrate Neo app', 'convert to CF', or 'Neo to Cloud Foundry migration'.

Source facts

Repository
SAP-samples/btp-neo-java-app-migration
Last source activity
August 12, 2026 at 13:50
Detected SKILL.md language
English
Stars
6
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
neo-to-cf-migration-orchestrator
description
Invoke this skill to orchestrate complete Neo to Cloud Foundry migration. Analyzes the Neo app, creates a migration plan, and dispatches each migration scenario (Jakarta, SDK, auth, persistence, destinations, etc.) to a separate subagent so the orchestrator's context stays lean across the full 5–14 step pipeline. Use when user says 'migrate Neo app', 'convert to CF', or 'Neo to Cloud Foundry migration'.
disable-model-invocation
false
allowed-tools
Agent, Read, Edit, Write, Grep, Glob, Bash(curl *), Bash(python3 *), Bash(mvn *), Bash(btp *), Bash(cf *), Bash(echo *), Bash(cat *), Bash(ls *), Bash(mkdir *), Bash(find *), Bash(grep *)
# Neo to Cloud Foundry Migration Orchestrator Orchestrates the complete migration of SAP BTP Neo Java applications to Cloud Foundry. ## Purpose This skill coordinates the end-to-end migration process by: 1. Analyzing the Neo application to detect required transformations 2. Creating a migration plan with skills in the correct order 3. **Dispatching each skill to its own subagent** so the orchestrator never loads the bodies of the 5–14 child skills into its own context 4. Validating the migration at each step using cheap filesystem and `mvn` checks 5. Generating the final deployment descriptor ## Orchestration Algorithm This skill follows the **Orchestrator-Worker pattern** with a verification gate between steps: - **Orchestrator** (this skill, running in your main context): plans, dispatches, verifies, and recovers. Holds only the plan, status log, and short worker reports. - **Workers** (subagents you spawn via the `Agent` tool): each handles one self-contained, idempotent unit of work in a fresh context and returns a ≤30-line structured report. - **Gate**: after each worker returns SUCCESS, the orchestrator advances to the next step. The worker's verification output is trusted — the orchestrator does NOT re-run the same verification. ### Dispatch tool Every subagent in this skill is spawned via the `Agent` tool. Use `subagent_type: "general-purpose"` for migration steps and `subagent_type: "Explore"` for read-only detection fan-outs. ``` Agent( subagent_type: "general-purpose", // or "Explore" for read-only description: "<3-5 word summary>", prompt: <the full prompt below> ) ``` Never emulate a subagent inline — that defeats the entire context-saving purpose. ### Concurrency policy | Phase | Mode | Cap | |-------|------|-----| | Phase 1 detection | **Fan-out (parallel)** | Up to 13 Explore agents in one batch (one per skill detection). All read-only — no file conflicts. | | Phase 3 execution | **Sequential** | 1 at a time. Feature skills mutate overlapping files (`pom.xml`, `web.xml`, `mtad.yaml` precursors); parallel runs would race. Step 3.3 (`mta-descriptor`) is run **inline** by the orchestrator — see Step 3.3 for why this is the one exception to the per-skill subagent rule. | | Phase 4 verification | Sequential | 1 subagent. | When fanning out in Phase 1, issue all `Agent` calls in a single message so they run concurrently (barrier-sync pattern). ### Failure & retry policy - **Max retries per step: 2.** After 2 failed subagent attempts on the same step, stop and surface to the user — do not loop indefinitely. - **Recoverable failures** (single-line tweak): fix in `$COPY_DIR` directly with `Edit`/`Write`, then re-run verification inline. Don't re-spawn a subagent for a one-line fix. - **Structural failures** (skill needs to re-run): re-spawn with the original prompt plus `Previous attempt failed because: <reason>. Address it and retry.` - **Hard stop conditions**: BOM version cannot be resolved from the registry; `mvn clean package` fails on a step that previously passed; `mtad.yaml` not produced in Phase 3.3 after 2 attempts. ### orchestrator.log format Every dispatch outcome appends exactly one line to `.migration/orchestrator.log` in this canonical format: ``` <ISO-8601-timestamp> phase=<n> skill=<name> status=<SUCCESS|FAILED|PARTIAL> attempt=<k> ``` Append-only. Never edit prior lines. Both the Resume protocol below and Step 3.4's hygiene rules read and write this single format — do not introduce variants. ### Resume protocol The orchestrator's own context may be summarized mid-migration. Resume is driven by `.migration/orchestrator.log` and `.migration/cf-migration-config.json`: ``` 1. cat .migration/orchestrator.log 2. last_success = last line whose status=SUCCESS resume_from = step immediately after last_success in the plan 3. PARTIAL is treated as FAILED for resume purposes: if the last line has status=PARTIAL or FAILED, the resume_from is THAT step (re-dispatch it; child skills are idempotent so re-running is safe). 4. If no log exists → start from Phase 0. If log exists but plan absent → re-run Phase 1 + 2 (cheap, idempotent) to rebuild the plan, then jump to resume_from. 5. Honor the max-retry cap: count the existing FAILED+PARTIAL lines for the same skill in the log; if already at 2, stop and surface to user instead of re-dispatching. ``` Each child skill is required to be idempotent (re-running on already-migrated files is a no-op or detects the migrated state). This means the worst case of a duplicate dispatch is a wasted subagent call, never a corrupted workspace. ### Why subagents (motivation, kept for context) Running each migration step inline would pull every child skill's `SKILL.md` (often hundreds of lines plus reference files) into the orchestrator's context. Across a full migration that's tens of thousands of tokens of skill bodies the orchestrator never needs to read — it only needs to know which skill to run next and whether the previous one succeeded. | Phase | Inline or subagent? | Why | |-------|---------------------|-----| | Phase 0 — copy | Inline | Just `cp -r`, trivial. | | Phase 1 — analysis | **Fan-out: 13 parallel Explore subagents** | Each does one skill's detection in parallel; orchestrator aggregates the small structured reports inline. | | Phase 2 — planning | Inline | The orchestrator already has the aggregated detection results; it just renders the plan and asks the user. No new file reads. | | Phase 3 — execution (feature skills, Steps 3.1–3.2) | **One general-purpose subagent per skill, sequential** | The original motivation — see the dispatch pattern below. | | Phase 3 — execution (`mta-descriptor`, Step 3.3) | **Inline** in the orchestrator's context | One-shot, last step, and `mtad.yaml` is THE deliverable. The orchestrator already has the cross-skill rules and feature-skill list it needs to feed the descriptor; the subagent dispatch was a translation step that introduced drift. See Step 3.3. | | Phase 4 — verification | **One general-purpose subagent** | `mvn clean package` output, recursive grep, file listings. The subagent returns pass/fail + last 10 lines on failure. | See the per-phase dispatch prompts in **Phase 1.0**, **Phase 3** (Step 3.1–3.2 for subagent feature skills; Step 3.3 runs inline), and **Phase 4.0**. ## Artifact versions — resolve, don't invent Never write an artifact version you remember from training data. SAP BOMs (`cf-tomcat-bom`, `sdk-modules-bom`, `cf-tomee-bom`, …) release frequently, and a number that doesn't exist in the registry breaks the BOM import with `Non-resolvable import POM`, which cascades into `'dependencies.dependency.version' is missing` for every dependency the BOM manages. Resolve each SAP BOM with a one-line lookup against Maven Central — use this exact form, do not hand-pick a number: ```bash latest_version () { curl -fsS --max-time 10 \ "https://search.maven.org/solrsearch/select?q=g:$1+AND+a:$2&core=gav&rows=20&wt=json" \ | jq -r '.response.docs | map(select(.v | test("^[0-9]+(\\.[0-9]+)*$"))) | sort_by(-.timestamp) | .[0].v' } latest_version com.sap.cloud.sjb.cf cf-tomcat-bom latest_version com.sap.cloud.sdk sdk-modules-bom latest_version com.sap.cloud.sjb.cf cf-tomee-bom # only if migrating to TomEE ``` Each invocation prints exactly one line: the latest *release* version. The subagent must capture that line and substitute it for the `RESOLVED_*` placeholders the child skills (`sdk-replacement`, `keystore-credstore`, `tomee-runtime`) ship in their pom snippets. If a lookup returns empty or `curl` exits non-zero — network failure, registry change — the subagent must stop and report. Do **not** ask another subagent to "just pick a recent one," do **not** fall back to a number from training data, and do **not** patch a version into the descriptor yourself. Other identifiers the skills prescribe — buildpack names (`sap_java_buildpack_jakarta`, not `sap_java_buildpack`), service names, plan names — are fixed strings, not version numbers. Use them exactly as the child skill specifies. ## Full Subaccount Migration Order When migrating a complete Neo subaccount (platform configuration + one or more applications), execute the phases in this order. Phases 1 and 3 run **once per subaccount**; Phase 2 runs **once per application**. ``` PHASE 0: Tooling setup — once Install CF CLI + BTP CLI, login to both PHASE 1: Subaccount export — once (read-only, Neo side) subaccount-trust-migrator ← export + import in one pass (in-memory, no disk files) subaccount-roles-export ← export now; import deferred to Phase 5 (destinations are NOT exported to file — migrated directly in Phase 3 via neo-destinations-keystores-migrator) PHASE 2: Per-app code migration — repeat for each app directory For each app: jakarta-java25-migration sdk-replacement authentication-xsuaa ← creates xs-security.json + role-collections [feature skills: destinations, persistence-hana, etc.] mta-descriptor PHASE 3: Platform import — once (CF side, before deploy) (trust already imported in Phase 1 by subaccount-trust-migrator) (roles-import is NOT here — deferred) PHASE 4: Deploy all apps — once per app mvn clean package -DskipTests cf deploy . -f PHASE 5: Post-deploy — once (after ALL apps deployed) neo-destinations-keystores-migrator ← requires CF apps to exist for app-level binding subaccount-roles-import ← NOW: live XSUAA appIds exist assigns role-templates + users to collections ``` > **Why roles-import is last:** `btp add security/role` requires the live XSUAA `appId` (e.g. `myapp!t1234`) which is only assigned after the first `cf deploy`. Role collections are created by `authentication-xsuaa` via `xs-security.json` + deployment — `subaccount-roles-import` only links role-templates into those collections and assigns users. ### Multi-App Notes For a subaccount with multiple applications: - Phases 0, 1, 3, and 5 run **once** for the whole subaccount - Phase 2 runs **once per app directory** — each app gets its own `xs-security.json`, `approuter/`, and `mtad.yaml` - Phase 4 runs **once per app** — deploy each app separately with `cf deploy . -f` from its directory - Phase 5 reads all apps from `.migration/neo-roles.json` and resolves each against live CF XSUAA apps in a single pass — run it only after **all** apps from Phase 4 are successfully deployed - If one app fails to deploy, `subaccount-roles-import` will flag it and can be re-run after the issue is fixed --- ## Trigger This skill is triggered when the user requests: - "Migrate my Neo app to CF" - "Convert this application to Cloud Foundry" - "Migration from Neo to Cloud Foundry" - "Help me migrate to CF" - Any request involving Neo to CF migration ## Migration Workflow ``` +------------------------------------------------------------------+ | MIGRATION WORKFLOW | +------------------------------------------------------------------+ | | | PHASE 1: ANALYSIS | | ----------------- | | Scan the application to identify which skills are needed: | | - pom.xml - Neo dependencies, Java version | | - web.xml - Resource references, auth config | | - Java files - Neo API imports | | | | PHASE 2: PLANNING | | ---------------- | | Create ordered migration plan based on detection results | | Present plan to user for approval | | | | PHASE 3: EXECUTION | | ----------------- | | Apply skills in dependency order: | | 1. Foundation skills (always required) | | 2. Feature skills (based on detection) | | 3. Deployment skill (always last) | | | | PHASE 4: VERIFICATION | | --------------------- | | - Compile the application | | - Verify no Neo imports remain | | - Validate mtad.yaml structure | | | +------------------------------------------------------------------+ ``` ## Skill Dependency Order Skills MUST be applied in this order: ``` FOUNDATION (Always Required) | +-> 1. jakarta-java25-migration | Migrate to Java 25 and Jakarta EE 10 | +-> 2. sdk-replacement Replace Neo Java Web API with SAP Cloud SDK | +-> 3. dependency-compatibility (if third-party libs detected) Resolve library compatibility for Java 25 / Jakarta / HANA Cloud FEATURES (Based on Detection) | +-> 4. approuter-setup (if web-facing app detected) | Set up SAP Application Router | +-> 5. authentication-xsuaa (if auth detected) | Set up XSUAA security configuration | +-> 6. persistence-hana (if DataSource detected) | Configure HANA Cloud database | +-> 7. destinations (if ConnectivityConfiguration detected) | Configure Destination service | +-> 8. connectivity-onpremise (if on-premise proxy detected) | Enable Cloud Connector connectivity | +-> 9. mail-destinations (if mail session detected) | Configure mail via destinations | +-> 10. document-management-sdm (if EcmService detected) | Migrate to Document Management Service | +-> 11. keystore-credstore (if KeyStoreService detected) | Migrate to Credential Store | +-> 12. tomee-runtime (if EJB detected - ALTERNATIVE to Tomcat) | Configure TomEE container | +-> 13. monitoring-logging (optional) Set up Cloud Logging DEPLOYMENT (Always Last) | +-> 14. mta-descriptor Generate mtad.yaml deployment descriptor ``` ## Phase 0: Create Migration Copy Before analyzing or modifying anything, create a sibling copy of the application directory. All migration work — by this orchestrator and every skill it invokes — is done on the copy. ```bash APP_DIR=$(pwd) APP_NAME=$(basename "$APP_DIR") COPY_DIR="$(dirname "$APP_DIR")/${APP_NAME}-cf-migration" if [ -d "$COPY_DIR" ]; then echo "Migration copy already exists at $COPY_DIR — using it." else cp -r "$APP_DIR" "$COPY_DIR" echo "Created migration copy at $COPY_DIR" fi cd "$COPY_DIR" ``` Now that we are inside the copy, create `.migration/` and save the config there: ```bash mkdir -p .migration ``` Save the paths to `.migration/cf-migration-config.json` (create or update): ```json { "sourceAppDir": "<original APP_DIR>", "migrationAppDir": "<COPY_DIR>" } ``` > All subsequent steps and all invoked skills must operate inside `$COPY_DIR`. The original `$APP_DIR` is never modified. The `.migration/` directory is inside the copy, not the original. ## Phase 1: Analysis ### Step 1.0: Fan Out Detection to Parallel Explore Subagents Phase 1 runs ~13 detection sweeps over every `pom.xml`, `web.xml`, and Java source tree in the project. The sweeps are **independent and read-only** — perfect for fan-out. Each sweep goes to its own `Explore` subagent, all dispatched in a single message so they run concurrently (barrier-sync pattern). The orchestrator then aggregates the 13 short reports inline (cheap, decision-shaped). #### Step 1.0a: First, discover the project layout once (inline)
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub