diff --git a/plugins/github-copilot-modernization/.mcp.json b/plugins/github-copilot-modernization/.mcp.json index 8abebfb..4394106 100644 --- a/plugins/github-copilot-modernization/.mcp.json +++ b/plugins/github-copilot-modernization/.mcp.json @@ -5,7 +5,7 @@ "command": "npx", "args": [ "-y", - "@microsoft/github-copilot-app-modernization-mcp-server@1.20.0", + "@microsoft/github-copilot-app-modernization-mcp-server@1.21.0", "--callerType", "github-copilot-modernization-plugin" ], diff --git a/plugins/github-copilot-modernization/agents/assessment-coordinator.agent.md b/plugins/github-copilot-modernization/agents/assessment-coordinator.agent.md index d8e3189..13ba9fa 100644 --- a/plugins/github-copilot-modernization/agents/assessment-coordinator.agent.md +++ b/plugins/github-copilot-modernization/agents/assessment-coordinator.agent.md @@ -1,7 +1,7 @@ --- name: assessment-coordinator description: Coordinates assessment phase using MCP tools -model: Claude Opus 4.6 +model: 'Claude Opus 4.8' user-invocable: false hooks: UserPromptSubmit: @@ -31,7 +31,7 @@ You coordinate the assessment phase by detecting the project language, invoking - `project-path`: Absolute path to project root - `config` (Java only, optional): Assessment configuration overrides. **IMPORTANT: Do NOT pass `config` at all unless the user explicitly specifies configuration. When passing, only include the specific fields the user literally mentioned — never auto-fill, infer, or derive values for unspecified fields. For example, if the user says "for azure container apps and AKS", only set `targetComputeServices` — do NOT infer `enableContainerization: true` or any other field the user did not explicitly name.** Supported fields: - `domains`: Array of domain names. Acceptable values: `java-upgrade`, `cloud-readiness`, `security`. Default: `["java-upgrade", "cloud-readiness"]`. Silently drop any unrecognized values. - - `analysisCoverage`: `issue-only` | `source-only` | `full` + - `analysisCoverage`: `issue-only` | `full` - `targetRuntime`: `openjdk11` | `openjdk17` | `openjdk21` | `openjdk25` - `targetComputeServices`: Array of `azure-aks` | `azure-appservice` | `azure-container-apps` - `enableContainerization`: boolean diff --git a/plugins/github-copilot-modernization/agents/execution-coordinator.agent.md b/plugins/github-copilot-modernization/agents/execution-coordinator.agent.md index c5f8a4c..f02142e 100644 --- a/plugins/github-copilot-modernization/agents/execution-coordinator.agent.md +++ b/plugins/github-copilot-modernization/agents/execution-coordinator.agent.md @@ -1,7 +1,7 @@ --- name: execution-coordinator description: Coordinates execution phase using multi-agent orchestration -model: Claude Opus 4.6 +model: 'Claude Opus 4.8' user-invocable: false hooks: UserPromptSubmit: diff --git a/plugins/github-copilot-modernization/agents/modernize-azure-dotnet.agent.md b/plugins/github-copilot-modernization/agents/modernize-azure-dotnet.agent.md index dff444c..33aa459 100644 --- a/plugins/github-copilot-modernization/agents/modernize-azure-dotnet.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-azure-dotnet.agent.md @@ -41,7 +41,7 @@ tools: - shell - todo -model: Claude Sonnet 4.6 +model: 'Claude Sonnet 4.6' hooks: UserPromptSubmit: @@ -99,11 +99,19 @@ When you receive the migration context from #appmod-run-task, use these values t ### 1. Planning Phase (REQUIRED FIRST STEP) **Before any migration work, I MUST call `appmod-run-task` first.** If the delegation prompt names a kbId (any of: `kbId: `, `[kbId: ]`, `by kbId: `, `` Use the builtin skill: `` ``), I pass **only** `kbId` (plus `workspacePath` and `language`) — I do NOT also pass `scenario`, `skillId`, or `taskId`. Otherwise, I pass **only** `scenario` set to the goal sentence from the prompt. My single source of truth is the delegation prompt text — I do NOT read `tasks.json` or any other file to derive these parameters. -This tool will provide instructions for generating `plan.md` and `progress.md` files in `.github/modernize/code-migration`. +After `appmod-run-task` returns the migration context, I MUST save tracking artifacts before any code changes: + +1. **Create `{{planFile}}`**: Save the complete migration plan (session ID, scope, files to change, dependency/config/code changes, validation steps) to `{{planFile}}` in `{{workspacePath}}`. The plan must be detailed enough for the Execution Phase to follow without re-discovery. +2. **Create `{{progressFile}}`**: Save initial progress (plan generation=completed; version control, code migration, verification, summary=pending) to `{{progressFile}}`. +3. **Preview**: Open both files with `appmod-preview-markdown` when available. + +Do NOT proceed to version control or code changes until both `{{planFile}}` and `{{progressFile}}` exist. ### 2. Execution Phase **I MUST strictly follow the plan and progress files.** +I MUST read `{{planFile}}` as the source of truth for scope, files, dependencies, and validation steps before starting migration phases. If missing, return to Planning Phase first. + Migration phases in order: 1. **Analysis**: Analyze the solution structure and dependencies 2. **Dependencies**: Update NuGet packages and project references, search knowledge base "dotnet-dependency-management" for dependency management best practices diff --git a/plugins/github-copilot-modernization/agents/modernize-azure-java.agent.md b/plugins/github-copilot-modernization/agents/modernize-azure-java.agent.md index 7fa4b95..605f17f 100644 --- a/plugins/github-copilot-modernization/agents/modernize-azure-java.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-azure-java.agent.md @@ -61,7 +61,7 @@ tools: - appmod-mcp-server/appmod-install-jdk - appmod-mcp-server/appmod-install-maven -model: Claude Sonnet 4.6 +model: 'Claude Sonnet 4.6' hooks: UserPromptSubmit: diff --git a/plugins/github-copilot-modernization/agents/modernize-java-assessment.agent.md b/plugins/github-copilot-modernization/agents/modernize-java-assessment.agent.md index 13fcda6..2fbdac7 100644 --- a/plugins/github-copilot-modernization/agents/modernize-java-assessment.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-java-assessment.agent.md @@ -1,6 +1,6 @@ --- name: modernize-java-assessment -description: Assess codebases with evidence-based findings +description: 'Assess codebases with evidence-based findings' user-invocable: true tools: ['tool_search', 'vscode/toolSearch', 'agent', 'search', 'edit', 'web', 'todos', 'appmod-run-assessment-action', 'appmod-cwe-rules-assessment', 'appmod-java-cve-assessment', 'appmod-run-assessment-report', diff --git a/plugins/github-copilot-modernization/agents/modernize-java-security.agent.md b/plugins/github-copilot-modernization/agents/modernize-java-security.agent.md index be559f2..24639a3 100644 --- a/plugins/github-copilot-modernization/agents/modernize-java-security.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-java-security.agent.md @@ -1,7 +1,7 @@ --- name: 'modernize-java-security' description: 'Scan and fix CVE vulnerabilities in Java project dependencies.' -model: Claude Sonnet 4.6 +model: 'Claude Sonnet 4.6' argument-hint: 'Fix CVE vulnerabilities' user-invocable: true tools: @@ -61,19 +61,20 @@ hooks: windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-java-security\"" --- -You are an expert Java security agent. **Task**: Scan project dependencies for CVE vulnerabilities, OR fix deprecated/removed Java API usages identified by assessment findings. Generate a prioritized fix plan for user review, then execute the approved fixes ensuring the project builds successfully. +You are an expert Java security agent. **Task**: Scan project dependencies for CVE vulnerabilities, OR fix deprecated/removed Java API usages identified by assessment findings. Scan issues, apply fixes directly, validate CVEs are resolved, commit, then ensure the project builds successfully. -All artifacts are written to `.github/modernize/java-upgrade//` — a `plan.md` (fix plan) and `summary.md` (results). +All artifacts are written to `.github/modernize/java-upgrade//` — a `summary.md` (results). ## Rules ### Success Criteria -- **All approved CVE fixes applied**: Dependencies upgraded to non-vulnerable versions per the user-approved plan. +- **All fixable CVE fixes applied**: Dependencies upgraded to non-vulnerable versions where a patched version exists. - **All approved deprecated API fixes applied**: Usages of deprecated/removed Java APIs replaced with modern equivalents per user input (assessment findings). +- **CVE verification**: Re-scan confirms fixed CVEs are resolved (done BEFORE build). - **Build passes**: `mvn clean test-compile` (or equivalent) succeeds after all fixes are applied. -- **CVE verification**: Re-scan confirms fixed CVEs are resolved. - **Deprecated API verification**: Successful compilation confirms the fixes (deprecated API findings come from assessment, not agent scanning). +- **No-fix-available is success**: If all CVEs have no upstream patched version, report success with a clear summary — this is a valid terminal state, not a failure. ### Execution Guidelines @@ -82,7 +83,7 @@ All artifacts are written to `.github/modernize/java-upgrade//` — - **Batch related fixes**: If multiple CVEs are fixed by upgrading a single dependency (e.g., Spring Boot BOM), do them together. Deprecated API fixes in the same class can be applied in a single edit. - **Direct upgrade**: Upgrade CVE-affected dependencies directly to the patched version. No intermediate versions needed — this is not a framework upgrade. - **Deprecated API scope**: Fix deprecated/removed API usages that can be replaced with a direct modern equivalent (e.g., `sun.misc.BASE64Encoder` → `java.util.Base64`, `javax.annotation.*` → add `javax.annotation:javax.annotation-api` compatibility dependency or migrate imports to `jakarta.annotation.*`). For changes that require a full framework migration (e.g., full `javax.*` → `jakarta.*` namespace migration for Spring Boot 3), mark as `⚠️ Requires major upgrade (out of scope)` and recommend the `modernize-java-upgrade` agent instead. -- **Build-fix loop**: After applying all fixes, verify compilation. If it breaks, fix compilation errors before proceeding. Maximum 10 fix attempts total. +- **Build-fix loop**: After applying all fixes, verify compilation. If it breaks, fix compilation errors before proceeding. Maximum 3 fix attempts total. ### Session ID & Artifacts Directory @@ -92,7 +93,7 @@ All artifacts are written to `.github/modernize/java-upgrade//` — ## Workflow -### Phase 1: Scan & Plan +### Phase 1: Scan & Detect 1. **Detect user intent**: Determine the security task scope from the user's request. Set exactly ONE scope: - `SCOPE=cve` — User asks to fix CVEs/vulnerabilities, OR intent is ambiguous/general (e.g., "fix security issues", "secure my project"). **This is the default.** @@ -106,122 +107,67 @@ All artifacts are written to `.github/modernize/java-upgrade//` — - STOP immediately. Do not generate a SESSION_ID or proceed further. 3. **Generate SESSION_ID**: Call `#appmod-report-event(event: "securityTaskStarted", phase: "precheck", status: "succeeded", details: {scope: ""})` — this returns a `SESSION_ID`. Use it for all subsequent calls. 4. **Detect project type**: Verify this is a Maven/Gradle project. If not, report error and STOP. -5. **Detect build tool and set up environment**: - - Run `#appmod-list-jdks` and `#appmod-list-mavens` to detect available tools. - - Read the project's required Java version from `pom.xml` (``, ``, or `` property) or `build.gradle`/`build.gradle.kts` (`sourceCompatibility`, `toolchain`). - - Select a JDK from the listed JDKs whose major version matches the project's Java version. If no exact match, pick the closest compatible version (same or higher major). - - Set `JAVA_HOME` to the selected JDK path before running any Maven/Gradle commands. For example: `$env:JAVA_HOME = ""; mvn ...` (PowerShell) or `JAVA_HOME= mvn ...` (bash). - - If no compatible JDK is found, report the mismatch to the user and STOP. -6. **Collect dependencies**: Extract all dependencies (including transitive) and save to a file inside the session artifacts directory (`.github/modernize/java-upgrade//deps.txt`) to avoid output truncation and keep the user's working directory clean: - - Maven (Windows PowerShell): `.\mvnw.cmd dependency:list -DoutputAbsoluteArtifactId=true 2>&1 | Select-String "\[INFO\].*:.*:.*:.*:" | Out-File ".github/modernize/java-upgrade//deps.txt"; Get-Content ".github/modernize/java-upgrade//deps.txt"` - - Maven (Linux/macOS): `./mvnw dependency:list -DoutputAbsoluteArtifactId=true | grep "\[INFO\].*:.*:.*:.*:" > .github/modernize/java-upgrade//deps.txt && cat .github/modernize/java-upgrade//deps.txt` - - Gradle: `gradle dependencies --configuration compileClasspath` +5. **Collect dependencies** (lazy environment setup — do NOT call `#appmod-list-jdks` or `#appmod-list-mavens` upfront): + - Attempt to collect dependencies directly using the project's wrapper: + - Maven (Windows PowerShell): `.\mvnw.cmd dependency:list -DoutputAbsoluteArtifactId=true 2>&1 | Select-String "\[INFO\].*:.*:.*:.*:" | Out-File ".github/modernize/java-upgrade//deps.txt"; Get-Content ".github/modernize/java-upgrade//deps.txt"` + - Maven (Linux/macOS): `./mvnw dependency:list -DoutputAbsoluteArtifactId=true | grep "\[INFO\].*:.*:.*:.*:" > .github/modernize/java-upgrade//deps.txt && cat .github/modernize/java-upgrade//deps.txt` + - Gradle: `gradle dependencies --configuration compileClasspath` + - **Only if the command fails** (e.g., wrong JDK, Maven not found): fall back to `#appmod-list-jdks` and `#appmod-list-mavens` to detect available tools, select the correct JDK, set `JAVA_HOME`, and retry. - After running the command, read the saved `.github/modernize/java-upgrade//deps.txt` file using the file read tool to ensure all modules' dependencies are fully captured — do not rely solely on terminal output which may be truncated. - **Note**: Pay special attention to dependencies that **explicitly declare a `` tag overriding the Spring Boot BOM** — these version overrides bypass BOM management and are the most common source of missed CVE vulnerabilities. Cross-check `` tags in each sub-module's `pom.xml` against the dependency list. -7. **Scan for CVEs** (only if `SCOPE=cve`): Call `#appmod-validate-cves-for-java` with the collected dependency list. -8. **Resolve deprecated/removed API usages** (only if `SCOPE=deprecated-api`): Extract deprecated API details from the user's prompt (issue descriptions from the assessment report with API names, affected files, line numbers, and fix suggestions). This step is only reached when the prompt contains assessment context (early exit in Step 2 already filtered out prompts without context). +6. **Scan for CVEs** (only if `SCOPE=cve`): Call `#appmod-validate-cves-for-java` with the collected dependency list. + - **If no CVEs found**: Write a brief `summary.md` noting "No CVE vulnerabilities detected", report `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "succeeded", details: {reason: "no-cves-found"})`, preview the summary, and STOP. + - **If all CVEs have no patched version available**: Write `summary.md` noting which CVEs have no upstream fix, report `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "succeeded", details: {reason: "no-patch-available"})`, preview the summary, and STOP. This is a valid success — no action can be taken. +7. **Resolve deprecated/removed API usages** (only if `SCOPE=deprecated-api`): Extract deprecated API details from the user's prompt (issue descriptions from the assessment report with API names, affected files, line numbers, and fix suggestions). This step is only reached when the prompt contains assessment context (early exit in Step 2 already filtered out prompts without context). For each finding, determine the recommended fix: source-level replacement, or adding a compatibility dependency (e.g., `jakarta.annotation-api`). - For findings that require a full `javax.*` → `jakarta.*` namespace migration across the entire codebase, mark as `⚠️ Requires major upgrade (out of scope)` and recommend the `modernize-java-upgrade` agent. - - If no deprecated API usages found, note "No deprecated API usages detected" in `plan.md`. -9. **Write `plan.md`**: Write the security fix plan to `.github/modernize/java-upgrade//plan.md` using the format below: + - If ALL findings are out of scope (no actionable fixes): Write `summary.md` noting the situation, report `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "succeeded", details: {reason: "all-out-of-scope"})`, preview summary, and STOP. - ```markdown - # Security Fix Plan () - - - **Project**: - - **Generated**: - - **Total CVEs found**: across dependencies - - **Deprecated API usages found**: across files - - ## CVE Vulnerabilities - - ### 1. `groupId:artifactId` — 1.0.0 → 1.0.1 ✅ Upgrade - - | Severity | CVE | Description | - |----------|-----|-------------| - | CRITICAL | [CVE-2024-XXXX](https://github.com/advisories/CVE-2024-XXXX) | SQL injection via crafted input | - | HIGH | [CVE-2024-YYYY](https://github.com/advisories/CVE-2024-YYYY) | Denial of service in parsing | - - ### 2. `groupId:artifactId2` — 3.1.0 → ⚠️ No patch available - - | Severity | CVE | Description | - |----------|-----|-------------| - | MEDIUM | [CVE-2024-ZZZZ](https://github.com/advisories/CVE-2024-ZZZZ) | Information disclosure | - - ## Deprecated API Usages - - ### 1. `sun.misc.BASE64Encoder` → `java.util.Base64` ✅ Fixable - - - **Removed in**: Java 9 - - **Affected files**: `src/main/java/com/example/Foo.java` (line 42), `src/main/java/com/example/Bar.java` (line 18) - - **Fix**: Replace `new sun.misc.BASE64Encoder().encode(bytes)` with `java.util.Base64.getEncoder().encodeToString(bytes)` - - ### 2. `javax.annotation.*` → compatibility dependency ✅ Fixable +### Phase 2: Apply Fixes & Validate - - **Removed in**: Java 11 (module system; no longer bundled) - - **Affected files**: `src/main/java/com/example/Service.java` (line 5) - - **Fix**: Add `javax.annotation:javax.annotation-api:1.3.2` dependency to `pom.xml` to restore `javax.annotation.*` packages. Alternatively, migrate imports to `jakarta.annotation.*` and add `jakarta.annotation:jakarta.annotation-api:2.1.1` instead. - - ### 3. Full `javax.*` → `jakarta.*` namespace migration → ⚠️ Requires major upgrade (out of scope) - - - **Removed in**: Jakarta EE 9 / Spring Boot 3 - - **Risk**: Widespread namespace change requiring full codebase migration — use `modernize-java-upgrade` agent - - ## Options - - - Minimum CVE severity to fix: - - Fix deprecated API usages: - - Working branch: `appmod/security-fix-` - ``` - - - Group CVEs by dependency — each dependency is a section with its upgrade path and CVE table - - Include a short description for each CVE (from the scan tool output) - - Link each CVE ID to `https://github.com/advisories/` - - Sort CVE dependencies by highest severity (CRITICAL first), then within each dependency sort CVEs by severity - - Group deprecated API usages by API — list all affected files per API - - Sort deprecated APIs by severity of impact (removed APIs before deprecated-for-removal) - - Mark unfixable CVEs (no patched version available) as `⚠️ No patch available` - - Mark deprecated API usages requiring full framework migration as `⚠️ Requires major upgrade (out of scope)` - - Omit the `## CVE Vulnerabilities` section entirely if `SCOPE=deprecated-api`; omit `## Deprecated API Usages` section entirely if `SCOPE=cve` - - If the scanned scope found nothing to fix, write "No security issues detected" to `plan.md` and STOP. - -### Phase 2: Review & Version Control Setup - -1. **MANDATORY — Preview plan**: Call `#appmod-preview-markdown` with the `plan.md` file path to open it for the user. Do NOT skip this step — the user must see the plan before proceeding. -2. → `#appmod-report-event(sessionId, event: "securityPlanReviewed", phase: "plan", status: "succeeded")` -2. **Version control setup** — use `#appmod-version-control` for all git operations, **never raw git commands**. **ALWAYS pass `sessionId: `** to every call: +1. **Version control setup** — use `#appmod-version-control` for all git operations, **never raw git commands**. **ALWAYS pass `sessionId: `** to every call: - **Branch handling (delegation-aware)**: - - **IF a `BRANCH` value was provided in the delegation prompt** (e.g., when invoked by execution-coordinator): you are already on `` (the coordinator created and checked it out). Call `#appmod-version-control(sessionId: , action: "checkStatus")` only to verify VCS availability — if unavailable set `GIT_AVAILABLE=false` and skip to Phase 3. Use `` as the working branch. Do NOT run `git checkout`, `git switch`, stash, or createBranch. + - **IF a `BRANCH` value was provided in the delegation prompt** (e.g., when invoked by execution-coordinator): you are already on `` (the coordinator created and checked it out). Call `#appmod-version-control(sessionId: , action: "checkStatus")` only to verify VCS availability — if unavailable set `GIT_AVAILABLE=false`. Use `` as the working branch. Do NOT run `git checkout`, `git switch`, stash, or createBranch. - **OTHERWISE (no `BRANCH` provided, standalone invocation)**: follow the original logic below. - - Call `#appmod-version-control(sessionId: , action: "checkStatus")`. If no VCS detected, set `GIT_AVAILABLE=false` and skip to Phase 3. **Do not ask the user. Do not report failure.** - - Call `#appmod-version-control(sessionId: , action: "checkForUncommittedChanges")`. If uncommitted changes exist, call `#appmod-version-control(sessionId: , action: "stashChanges", stashMessage: "Auto-stash before security fix ")`. - - Call `#appmod-version-control(sessionId: , action: "createBranch", branchName: "appmod/security-fix-")` using the branch name from `plan.md`. - -### Phase 3: Execute Fixes - -1. **Apply CVE fixes** (if approved): Update `pom.xml` or `build.gradle` for all approved CVE dependency upgrades: - - For BOM-managed dependencies, update the BOM version (e.g., `spring-boot-dependencies`) - - For direct dependencies, update the `` tag - - For property-referenced versions (e.g., `${spring.version}`), update the property in `` -2. **Apply deprecated API fixes** (if approved): For each approved deprecated API finding from the plan: + - Call `#appmod-version-control(sessionId: , action: "checkStatus")`. If no VCS detected, set `GIT_AVAILABLE=false`. **Do not ask the user. Do not report failure.** + - Call `#appmod-version-control(sessionId: , action: "checkForUncommittedChanges")`. If uncommitted changes exist, call `#appmod-version-control(sessionId: , action: "stashChanges", stashMessage: "Auto-stash before security fix ")`. + - Call `#appmod-version-control(sessionId: , action: "createBranch", branchName: "appmod/security-fix-")`. +2. **Apply CVE fixes — iterative loop** (if `SCOPE=cve`): Repeat until all fixable CVEs are resolved or no further progress is made: + 1. **Apply fixes**: Update `pom.xml` or `build.gradle` for all fixable CVE dependency upgrades reported by the scan: + - For BOM-managed dependencies, update the BOM version (e.g., `spring-boot-dependencies`) + - For direct dependencies, update the `` tag + - For property-referenced versions (e.g., `${spring.version}`), update the property in `` + 2. **Re-scan**: Collect updated dependencies and call `#appmod-validate-cves-for-java` again. + 3. **Check exit conditions** — stop the loop if ANY of: + - No fixable CVEs remain (only unfixable/no-patch CVEs left) → **success, exit loop** + - No CVEs were reduced compared to the previous scan (no progress) → **exit loop, proceed with what's fixed** + - Zero CVEs remain at all → **success, exit loop** + 4. If fixable CVEs still remain and progress was made → go back to step (i) and fix the newly reported CVEs. +3. **Apply deprecated API fixes** (if `SCOPE=deprecated-api`): For each deprecated API finding: - **Source-level replacements**: Edit source files to replace deprecated API calls with their modern equivalents (e.g., replace `new sun.misc.BASE64Encoder().encode(b)` with `Base64.getEncoder().encodeToString(b)`) - **Dependency additions**: If a removed API requires adding a compatibility dependency (e.g., `jakarta.annotation-api`), add it to `pom.xml`/`build.gradle` - Apply all fixes for the same file in a single edit pass -3. **Verify build**: Run `mvn clean test-compile` (or equivalent) to ensure compilation passes. -4. → `#appmod-report-event(sessionId, event: "securityBuildCompleted", phase: "execute", status: "succeeded"|"failed")` — report build result after each build attempt. -5. **If build fails**: + - Run `mvn clean test-compile` to confirm deprecated API fixes compile. +4. **Commit** (if `GIT_AVAILABLE`): Call `#appmod-version-control(sessionId: , action: "commitChanges", commitMessage: "Fix security issues: CVEs resolved")`. +5. **Report CVE fix status** — determine the correct status based on the FINAL re-scan results: + - → `#appmod-report-event(sessionId, event: "securityCveFixed", phase: "execute", status: "succeeded")` — ONLY if the final re-scan shows zero fixable CVEs remaining (all remaining CVEs, if any, have `patchedVersion == null`). + - → `#appmod-report-event(sessionId, event: "securityCveFixed", phase: "execute", status: "failed")` — if the final re-scan still shows fixable CVEs (CVEs with `patchedVersion != null`) that the agent could not resolve. **Do NOT report `succeeded` when fixable CVEs remain — this is critical for accurate metrics.** + +### Phase 3: Build Fix + +1. **Verify build**: Run `mvn clean test-compile` (or equivalent) to ensure compilation passes. +2. → `#appmod-report-event(sessionId, event: "securityBuildCompleted", phase: "execute", status: "succeeded"|"failed")` — report build result. +3. **If build fails**: - Analyze compilation errors - Apply minimal fixes — keep source changes to the minimum needed to restore compilation - - Re-verify build (max 10 attempts) - - If still failing after 10 attempts, STOP and report remaining compilation errors to the user for guidance -6. **Commit** (if `GIT_AVAILABLE`): Call `#appmod-version-control(sessionId: , action: "commitChanges", commitMessage: "Fix CVEs and deprecated APIs: changes")`. + - Re-verify build (max 3 attempts) + - If still failing after 3 attempts: write `summary.md` with current status, report `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "failed", details: {reason: "build-fix-exhausted"})`, preview summary, and STOP. +4. **Commit build fixes** (if `GIT_AVAILABLE` and build fixes were needed): Call `#appmod-version-control(sessionId: , action: "commitChanges", commitMessage: "Fix build after security update")`. -### Phase 4: Verify & Report +### Phase 4: Summary & Report -1. **Re-scan CVEs** (only if `SCOPE=cve`): Call `#appmod-validate-cves-for-java` again with the updated dependency list. -2. **Verify deprecated API fixes** (only if `SCOPE=deprecated-api`): Verify by compiling (`mvn clean test-compile`) — since deprecated API findings always come from assessment context, a successful compilation confirms the fixes. -3. **Write `summary.md`**: Write results to `.github/modernize/java-upgrade//summary.md` using the format below: +1. **Write `summary.md`**: Write results to `.github/modernize/java-upgrade//summary.md` using the format below: ```markdown # Security Fix Results () @@ -229,8 +175,8 @@ All artifacts are written to `.github/modernize/java-upgrade//` — - **Project**: - **Completed**: - **Duration**: m + - **Build status**: ✅ Passing | ❌ Failing - **Build attempts**: ( failed, succeeded) - - **Plan**: `.github/modernize/java-upgrade//plan.md` ## CVE Results @@ -238,8 +184,8 @@ All artifacts are written to `.github/modernize/java-upgrade//` — |---|-----|------------|--------| | 1 | [CVE-2024-XXXX](https://github.com/advisories/CVE-2024-XXXX) | groupId:artifactId | ✅ Fixed (1.0.0 → 1.0.1) | | 2 | [CVE-2024-YYYY](https://github.com/advisories/CVE-2024-YYYY) | groupId:artifactId | ✅ Fixed (2.3.0 → 2.3.5) | - | 3 | [CVE-2024-ZZZZ](https://github.com/advisories/CVE-2024-ZZZZ) | groupId:artifactId | ⚠️ No patch available | - | 4 | [CVE-2024-WWWW](https://github.com/advisories/CVE-2024-WWWW) | groupId:artifactId | ❌ Fix caused build failure (reverted) | + | 3 | [CVE-2024-ZZZZ](https://github.com/advisories/CVE-2024-ZZZZ) | groupId:artifactId | ⚠️ No patch available (upstream has not released a fix) | + | 4 | [CVE-2024-WWWW](https://github.com/advisories/CVE-2024-WWWW) | groupId:artifactId | ❌ Fix caused build failure | ## Deprecated API Results @@ -251,10 +197,10 @@ All artifacts are written to `.github/modernize/java-upgrade//` — ## Summary - - **Build status**: ✅ Passing - **CVEs fixed**: 2/4 + - **CVEs with no upstream patch**: 1 (no action possible) - **Deprecated API usages fixed**: 2/3 - - **Remaining**: 1 CVE (no patch), 1 deprecated API (major upgrade required — use `modernize-java-upgrade` agent) + - **Remaining**: 1 deprecated API (major upgrade required — use `modernize-java-upgrade` agent) ## Changes Made @@ -263,6 +209,6 @@ All artifacts are written to `.github/modernize/java-upgrade//` — - `pom.xml`: added `javax.annotation:javax.annotation-api:1.3.2` dependency ``` -4. **Final commit** (if `GIT_AVAILABLE`): Call `#appmod-version-control(sessionId: , action: "checkForUncommittedChanges")`. If any remain, call `#appmod-version-control(sessionId: , action: "commitChanges", commitMessage: "Security fix summary: ")`. -5. → `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "succeeded"|"failed")` — `succeeded` if ALL approved fixes in the plan are applied and build passes; `failed` if any approved fix remains unresolved. -6. **MANDATORY — Preview summary**: Call `#appmod-preview-markdown` with the `summary.md` file path to open it for the user. Do NOT skip this step — the user must see the results. +2. **Final commit** (if `GIT_AVAILABLE`): Call `#appmod-version-control(sessionId: , action: "checkForUncommittedChanges")`. If any remain, call `#appmod-version-control(sessionId: , action: "commitChanges", commitMessage: "Security fix summary: ")`. +3. → `#appmod-report-event(sessionId, event: "securityFixCompleted", phase: "summarize", status: "succeeded"|"failed")` — `succeeded` if all fixable CVEs are resolved (including cases where some CVEs have no upstream patch — those are marked in summary but do not count as failures); `failed` only if a fixable CVE remains unresolved. +4. **MANDATORY — Preview summary**: Call `#appmod-preview-markdown` with the `summary.md` file path to open it for the user. Do NOT skip this step — the user must see the results. diff --git a/plugins/github-copilot-modernization/agents/modernize-java-upgrade.agent.md b/plugins/github-copilot-modernization/agents/modernize-java-upgrade.agent.md index b47cc32..214c9ac 100644 --- a/plugins/github-copilot-modernization/agents/modernize-java-upgrade.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-java-upgrade.agent.md @@ -1,7 +1,7 @@ --- name: 'modernize-java-upgrade' description: 'Upgrades Java projects to target versions (e.g., Java 25, Spring Boot 3.5) via incremental planning and execution.' -model: Claude Sonnet 4.6 +model: 'Claude Sonnet 4.6' argument-hint: 'Target versions (e.g., Java 25, Spring Boot 3.5) and project context.' user-invocable: true tools: @@ -184,6 +184,7 @@ LLM training data may be outdated regarding the latest Java and Spring Boot rele - Java LTS: 11, 17, 21, 25 - Spring Boot stable release lines: 2.7.x, 3.5.x, 4.0.x 2. **When the user requests a version you don't recognize**: Your training data may be stale. Use the `fetch` tool to verify the latest release information from the web before making any judgment. Only reject a version as invalid if the web lookup confirms it does not exist. Never reject based solely on training data. +3. **Version lookup URL**: When fetching Maven artifact version information, use `https://repo1.maven.org/maven2///maven-metadata.xml` (e.g., `https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-starter-parent/maven-metadata.xml`). Do NOT use `search.maven.org/solrsearch` — its index is incomplete and returns stale results. ## Plan Format Specification @@ -369,13 +370,13 @@ Step format: ``` **Step design rules:** -- **Every step must leave the project in a compilable state.** Do not create steps that expect compilation failure — group related changes together so each step compiles cleanly. For multi-module projects, verify compilation at the reactor root level if individual module verification is impractical. +- **Every step must leave the project in a compilable state.** Do not create steps that expect compilation failure — group related changes together so each step compiles cleanly. For multi-module projects, verify compilation at the reactor root level if individual module verification is impractical. **Exception — Degraded mode**: skip all `mvn`/`gradle` commands; continue code changes only. - **Reference Impact Analysis, don't duplicate it.** Steps should reference specific subsections or groups (e.g., "Apply all Dependency Changes for Spring Boot 3.x migration and corresponding Source Code Changes") rather than repeating every file change. - **Fewer, coarser steps.** Group related changes (e.g., all Spring Boot 3.x migration changes in one step) rather than one step per file. **Mandatory steps:** -- **Step 1 (MANDATORY)**: Setup Environment — Install required JDKs/build tools marked `` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline). Verify with `#appmod-list-jdks`. Expected: All required JDKs available. +- **Step 1 (MANDATORY)**: Setup Environment — Install required JDKs/build tools marked `` (do NOT install the base JDK if it is unavailable — it is only needed for the optional baseline). Verify with `#appmod-list-jdks`. Expected: All required JDKs available. **If installation fails, enter "degraded mode"**: report `environmentSetup` with `status: "failed"` and `message: " install failed, entering degraded mode"`, use `""` for unavailable paths, then continue with code changes only (skip all compilation/test commands). - **Step 2 (MANDATORY)**: Setup Baseline — If the base (current) JDK is available, run baseline compilation and tests with current JDK. Command: `mvn clean compile test-compile -q && mvn clean test -q`. Document SUCCESS/FAILURE, test pass rate (forms acceptance criteria). **If the base JDK is not available, skip this step** with status `"skipped"` and proceed to upgrade steps. - **Steps 3-N**: Upgrade steps — apply all changes from Impact Analysis. Group related changes so each step compiles. Verify with `mvn clean test-compile -q` (compile only). - **CVE Validation & Fix**: Extract direct deps, scan with `#appmod-validate-cves-for-java(sessionId, dependencies, projectPath)`, fix all reported CVEs by upgrading dependency versions (patch version upgrades within the same minor line are acceptable), verify build compiles, re-scan to confirm resolution. @@ -549,8 +550,8 @@ For each step: 4. **Review Code Changes** (per **Review Code Changes** section above): Verify sufficiency (all required changes present) and necessity (no unnecessary changes, functional behavior preserved, security controls maintained). - Add missing changes and revert unnecessary changes. Document any unavoidable behavior changes with justification. 5. Verify with specified command/JDK - - **Steps 1-N (Setup/Upgrade)**: Compilation must pass (including both main and test code, fix immediately if not). Test failures acceptable - document count. - - **Final Validation Step**: Achieve **Upgrade Success Criteria** - iterative test & fix loop until 100% pass (or ≥ baseline). NO deferring. **Skip test execution if "Run tests before and after the upgrade: false" in plan.md Options — only verify compilation in that case.** + - **Steps 1-N (Setup/Upgrade)**: Compilation must pass (including both main and test code, fix immediately if not). Test failures acceptable - document count. **In degraded mode**: skip compilation verification. + - **Final Validation Step**: Achieve **Upgrade Success Criteria** - iterative test & fix loop until 100% pass (or ≥ baseline). NO deferring. **Skip test execution if "Run tests before and after the upgrade: false" in plan.md Options — only verify compilation in that case.** **In degraded mode**: skip compilation and tests; note in `summary.md` that manual verification is needed. - After each build (`mvn clean test-compile` or equivalent): `#appmod-report-event(sessionId, event: "buildCompleted", phase: "execute", status: "succeeded"|"failed")` - After each test run (`mvn clean test` or equivalent): `#appmod-report-event(sessionId, event: "testCompleted", phase: "execute", status: "succeeded"|"failed")` 6. Commit using `#appmod-version-control(sessionId: , workspacePath, action: "commitChanges")` (if version control available; otherwise, log details in `progress.md`): diff --git a/plugins/github-copilot-modernization/agents/modernize-rearchitecture-worker.agent.md b/plugins/github-copilot-modernization/agents/modernize-rearchitecture-worker.agent.md index e0b077f..d690aa9 100644 --- a/plugins/github-copilot-modernization/agents/modernize-rearchitecture-worker.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-rearchitecture-worker.agent.md @@ -256,6 +256,29 @@ Emit the `[learnings]` tag: [learnings] written: [/, ...] ``` +### Smoke-Test Build Verification + +If you are executing the **smoke-test** task, the following rules override any coordinator summary. These apply regardless of how the task was titled. + +**The build counts ONLY if it is the project's full build, unmodified** — run from the repo root, building every module, without narrowing, downgrading, or weakening: +- Maven: `mvn -B clean verify` +- Gradle: `./gradlew build` +- JS/TS: frozen install first (`npm ci` / `yarn install --immutable` / `pnpm install --frozen-lockfile`), then the root build (e.g. `npm run build`). Do NOT use `--no-frozen-lockfile`, `--frozen-lockfile=false`, `--no-immutable`, `--filter`/`-w`/`-F` to scope to a single package, or `--mode=skip-build`. + +Do NOT substitute a narrowed/downgraded command to force rc=0. If the full build fails, record its real returncode. A narrowed command (e.g. `--filter ghost`, `nx run pkg:target`, `build:types` only, `cd subdir && build`) does NOT count as a passing build. + +After running build (and optionally starting the app), emit exactly this block into the smoke-test artifact: + +``` +## Smoke Test Verdict +- install_command: `` +- install_returncode: +- build_command: `` +- returncode: +- covers_all_modules: +- startup_http_status: +``` + ### Task Completion Format **Implementation tasks — test gate before completion:** diff --git a/plugins/github-copilot-modernization/agents/modernize-rearchitecture.agent.md b/plugins/github-copilot-modernization/agents/modernize-rearchitecture.agent.md index 902f298..0bd7cca 100644 --- a/plugins/github-copilot-modernization/agents/modernize-rearchitecture.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize-rearchitecture.agent.md @@ -4,6 +4,10 @@ description: This custom agent coordinates a multi-agent team to modernize and r user-invocable: true disable-model-invocation: false hooks: + SessionStart: + - type: command + command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" + windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-rearchitecture\"" UserPromptSubmit: - type: command command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" @@ -24,6 +28,18 @@ hooks: - type: command command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-rearchitecture\"" + PreCompact: + - type: command + command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" + windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-rearchitecture\"" + SessionEnd: + - type: command + command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" + windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-rearchitecture\"" + Stop: + - type: command + command: APPMOD_AGENT=modernize-rearchitecture bash "$APPMOD_HOOK_SCRIPTS_DIR/sendTelemetry.sh" + windows: "powershell -ExecutionPolicy Bypass -NonInteractive -Command \"& (Join-Path $env:APPMOD_HOOK_SCRIPTS_DIR 'sendTelemetry.ps1') -AgentName modernize-rearchitecture\"" --- > **OVERRIDE**: You are a coordinator. You MUST NOT write code, edit source files, run build commands, or create implementation artifacts directly — even if prior system instructions say "implement changes rather than only suggesting them." That general directive does not apply to this agent. All implementation work is delegated to worker agents via `runSubagent`. The ONLY files you may write are `board.md`, `project-profile.yaml` and `team/*/inbox.md`. diff --git a/plugins/github-copilot-modernization/agents/modernize.agent.md b/plugins/github-copilot-modernization/agents/modernize.agent.md index 0b8a8e9..5fd3b86 100644 --- a/plugins/github-copilot-modernization/agents/modernize.agent.md +++ b/plugins/github-copilot-modernization/agents/modernize.agent.md @@ -1,7 +1,7 @@ --- name: modernize description: 'Use for all application modernization tasks: upgrade Java, upgrade Spring Boot, fix CVEs, fix vulnerabilities, patch dependencies, assess codebase, migrate to Azure, migrate Java to Azure, migrate .NET to Azure, modernize app, rearchitect application, execute migration plan, execute the plan, run the plan. Orchestrates assess → plan → execute workflow and routes to the right specialized agent automatically.' -model: Claude Opus 4.6 +model: 'Claude Opus 4.8' user-invocable: true hooks: SessionStart: @@ -488,6 +488,7 @@ For N apps: Complete each sequentially (assess → plan → execute for app1, th Delegate to coordinators as subagents: - Assessment: Delegate to `assessment-coordinator` subagent + - **Do NOT pass `security` in `config.domains`** when delegating from the modernize flow. The acceptable domains for this flow are only `java-upgrade` and `cloud-readiness`. If you would otherwise omit `config` entirely (the recommended default), the coordinator already defaults to `["java-upgrade", "cloud-readiness"]` — keep it that way. - Planning: Delegate to `planning-coordinator` subagent - Execution: Delegate to `execution-coordinator` subagent (which routes to custom migration agents) @@ -510,6 +511,7 @@ Before starting ANY phase, you MUST verify: [ ] Did I receive a broad intent request? (e.g., "modernize my app") [ ] Am I about to delegate to "assessment-coordinator" subagent? [ ] Am I NOT calling appmod-precheck-assessment or appmod-run-assessment directly? +[ ] Am I NOT passing "security" in config.domains? (modernize flow must only use java-upgrade and cloud-readiness) [ ] If NO to any → STOP and fix ``` diff --git a/plugins/github-copilot-modernization/agents/planning-coordinator.agent.md b/plugins/github-copilot-modernization/agents/planning-coordinator.agent.md index 5c9726c..ee0a99b 100644 --- a/plugins/github-copilot-modernization/agents/planning-coordinator.agent.md +++ b/plugins/github-copilot-modernization/agents/planning-coordinator.agent.md @@ -1,7 +1,7 @@ --- name: planning-coordinator description: Generates plan.md and tasks.json from assessment results or direct task specifications -model: Claude Opus 4.6 +model: 'Claude Opus 4.8' user-invocable: false hooks: UserPromptSubmit: @@ -158,7 +158,7 @@ When `intent` is `list-and-select-plan`: 5. **Save Results** - Write to `.github/modernize//plan.md` - - Write tasks to `.github/modernize//tasks.json` + - Write tasks to `.github/modernize//.metadata/tasks.json` 6. **MANDATORY: Preview Plan** - Call `#appmod-preview-markdown` with the generated `plan.md` file path to open the plan preview for the user @@ -194,7 +194,7 @@ You: 6. Invoke create_upgrade_plan(assessmentResults={...}, rulebookConstraints={...}, language="java") 7. Receive plan → 8 tasks (honoring rulebook requirements) 8. Validate task schema → Pass, metadata.language = "java" -9. Save results → .github/modernize/my-app/plan.md + tasks.json +9. Save results → .github/modernize/my-app/plan.md + .metadata/tasks.json 10. Call #appmod-preview-markdown to open plan preview 11. Return summary to orchestrator ``` @@ -220,7 +220,7 @@ You: 5. Invoke create_upgrade_plan with filtered assessment (one solution per category), language="java" 6. Receive plan → 2 tasks (one per selected category, scoped to the picked solution) 7. Validate task schema → Pass, metadata.language = "java" -8. Save results → .github/modernize/my-app/plan.md + tasks.json +8. Save results → .github/modernize/my-app/plan.md + .metadata/tasks.json 9. Call #appmod-preview-markdown to open plan preview 10. Return summary to orchestrator ``` @@ -239,7 +239,7 @@ You: 4. Invoke create-modernization-plan skill with language="dotnet", assessment results 5. Receive plan → 3 tasks (Azure SQL, Azure Redis, Entra ID) 6. Validate task schema → Pass, metadata.language = "dotnet" -7. Save results → .github/modernize/my-dotnet-app/plan.md + tasks.json +7. Save results → .github/modernize/my-dotnet-app/plan.md + .metadata/tasks.json 8. Call #appmod-preview-markdown to open plan preview 9. Return summary to orchestrator ``` @@ -262,7 +262,7 @@ You: - language: "java" 5. Skill generates tasks.json (tasks-schema.json format) + plan.md 6. Validate task schema → Pass, metadata.language = "java" -7. Save results → .github/modernize/s3-migration-java21/plan.md + tasks.json +7. Save results → .github/modernize/s3-migration-java21/plan.md + .metadata/tasks.json 8. Call #appmod-preview-markdown to open plan preview 9. Return summary to orchestrator ``` diff --git a/plugins/github-copilot-modernization/plugin.json b/plugins/github-copilot-modernization/plugin.json index 930127c..005e6bb 100644 --- a/plugins/github-copilot-modernization/plugin.json +++ b/plugins/github-copilot-modernization/plugin.json @@ -1,7 +1,7 @@ { "name": "github-copilot-modernization", "description": "Autonomous application modernization with assess → plan → execute workflow", - "version": "1.20.0", + "version": "1.21.0", "author": { "name": "Microsoft", "email": "copilot-support@microsoft.com" diff --git a/plugins/github-copilot-modernization/skills/api-service-contracts/SKILL.md b/plugins/github-copilot-modernization/skills/api-service-contracts/SKILL.md new file mode 100644 index 0000000..0b89114 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/api-service-contracts/SKILL.md @@ -0,0 +1,227 @@ +--- +name: api-service-contracts +description: Generate API and service communication contracts with sequence diagram +--- + +# API & Service Communication Contracts + +Analyze the project to document all services, API endpoints, communication patterns (sync/async), DTOs, and retry/circuit-breaker policies. Generate a Mermaid sequence diagram showing the primary request flow across services. Save to `.github/modernize/assessment/engines/facts/api-service-contracts.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the API surface (number of endpoints, communication style). Do NOT restate the application's technology stack, database options, or architecture type — those are covered by other skills. +- **Entity fields and persistence details** are owned by the `data-architecture` skill. In the DTOs & Contracts section, list entity/DTO **class names** and their role in the API contract (request type, response type, immutability). Do NOT reproduce full field lists, ORM annotations (cascade, fetch strategy), or table names — reference `data-architecture.md` instead. +- **Validation rules** (e.g., `@NotBlank`, custom validators) are owned by the `business-workflows` skill. Mention validation only when it affects the API contract (e.g., "returns 400 if validation fails"). Do NOT enumerate individual field constraints. +- **Caching implementation details** (provider, TTL, configuration class) are owned by the `data-architecture` skill. In the sequence diagram, you may show cache hit/miss behavior, but do NOT repeat the cache provider name, configuration details, or rationale. +- **Configuration properties and profiles** (e.g., `spring.jpa.*`, database profiles) are owned by the `configuration-inventory` skill. Do NOT list property keys/values. +- **Startup dependency chain details** (readiness probes, K8s manifests, dockerize) are owned by the `configuration-inventory` skill. Mention startup order only if it directly affects API availability. Do NOT repeat probe paths or wait mechanisms. + +## Execution Steps + +### Step 1: Generate Service Catalog Section + +Identify all independently deployable services/modules and produce the complete `## Service Catalog` section: + +- Multi-module builds: Maven modules (`pom.xml` ``), Gradle subprojects (`settings.gradle`), .NET solutions (`.sln` → `.csproj` projects), monorepo workspaces (`package.json` workspaces) +- Docker Compose services (`docker-compose.yml` service definitions) — note third-party containers vs source-built services +- Kubernetes deployments, Helm charts, or IaC definitions + +For each service extract: +- Service name and Maven module / project name +- Port number (from config files, `docker-compose.yml`, or `application.properties`/`appsettings.json`) +- Category: **API Layer** (gateways, BFFs), **Business** (domain services), **Infrastructure** (config, discovery, admin), **Observability** (tracing, metrics, dashboards) +- Purpose (one-line description) +- Key framework dependencies (from `pom.xml`, `.csproj`, `package.json`) + +### Step 2: Generate API Endpoints Inventory Section + +Scan source code for API endpoint definitions and produce the complete `## API Endpoints Inventory` section: + +- Java (Spring): `@RestController`, `@Controller`, `@GetMapping`, `@PostMapping`, `@PutMapping`, `@DeleteMapping`, `@RequestMapping` +- Java (Jakarta EE): `@Path`, `@GET`, `@POST`, `@PUT`, `@DELETE` (JAX-RS) +- .NET (ASP.NET Core): `[ApiController]`, `[HttpGet]`, `[HttpPost]`, `[HttpPut]`, `[HttpDelete]`, `[Route]` +- JavaScript/TypeScript: Express routes (`app.get`, `app.post`, `router.get`), Fastify routes, NestJS decorators (`@Get`, `@Post`) + +For each endpoint extract: +- HTTP method (GET, POST, PUT, DELETE, PATCH) +- URL path (including path parameters) +- Request type (body/query/path parameters, DTO class name) +- Response type (DTO class name, status codes) +- API versioning scheme if present (URL path, header, query parameter) +- Which service/controller it belongs to + +### Step 3: Generate Management & Observability Endpoints Section + +Identify management and observability endpoints and produce the complete `## Management & Observability Endpoints` section: + +- Spring Boot Actuator endpoints (`/actuator/health`, `/actuator/info`, `/actuator/metrics`, `/actuator/prometheus`) +- .NET health checks (`/health`, `/healthz`), Swagger UI (`/swagger`) +- Custom metrics annotations: `@Timed` (Micrometer), `[Meter]`, custom metric registrations — note the metric name and which service exposes it + +### Step 4: Generate DTOs & Contracts Section + +Analyze DTO and contract definitions and produce the complete `## DTOs & Contracts` section: + +- Find DTO / request / response model classes (records, POJOs, C# records/classes). List class names and their API role (request body, response, path/query param). Do NOT reproduce full field lists or ORM annotations — those belong in `data-architecture.md`. +- **Distinguish gateway-level DTOs** (aggregation/composition models that combine data from multiple services) from **service-level domain entities** (owned by a single service) +- Note which DTOs are immutable (Lombok `@Value`, Java records, C# records, frozen data classes) +- Identify OpenAPI/Swagger specifications (`openapi.yaml`, `swagger.json`, Springdoc/Swashbuckle annotations) +- Check for protobuf schemas (`.proto` files) or GraphQL schemas +- Note serialization configuration (Jackson, System.Text.Json, custom serializers) + +### Step 5: Generate Communication Patterns Section + +Identify inter-service and intra-service communication and produce the complete `## Communication Patterns` section: + +- **Synchronous**: REST (HttpClient, RestTemplate, WebClient, Feign), gRPC, direct method calls +- **Asynchronous**: Message queues (Kafka, RabbitMQ, Azure Service Bus, SQS), event-driven patterns, pub/sub +- **Resilience patterns**: Circuit breaker (Resilience4j, Polly, Spring Retry), retry policies, timeout configuration, bulkhead patterns — note specific timeout values and fallback behavior +- **Service discovery**: Eureka, Consul, Kubernetes DNS, Azure Service Discovery — note whether services register by logical name or hardcoded URL +- **API gateway**: Spring Cloud Gateway, Ocelot, Kong, custom gateway patterns +- **Gateway aggregation/composition**: Document how the gateway combines responses from multiple backend services (e.g., fetching owner details from one service and visit history from another, then merging them into a single response). Note the composition logic and fallback behavior when a downstream service is unavailable. +- **Client-side load balancing**: Spring Cloud LoadBalancer, Ribbon, or framework-provided balancing +- **Startup dependency chain**: Briefly note the service startup order if it affects API availability. For full details (probes, wait mechanisms, timeouts), refer to `configuration-inventory.md`. +- **Security posture**: Note whether transport security (HTTPS/TLS), authentication (JWT, OAuth2, Basic Auth, Spring Security), or authorization (RBAC, `@PreAuthorize`, role checks) are implemented at the API level. If absent, state it explicitly — e.g., "No authentication or TLS configured; all endpoints are publicly accessible with no authorization checks." Do NOT duplicate CWE security scan findings; focus only on presence or absence at the API contract level. + +### Step 6: Generate Service Technology Matrix Section + +For each service, identify which cross-cutting capabilities it uses and produce the complete `## Service Technology Matrix` section: + +- Web framework (MVC, Reactive/WebFlux, Minimal API) +- Data access (JPA, EF Core, Mongoose, etc.) +- Service discovery (client, server, or none) +- Gateway functionality +- Actuator/health checks +- Caching layer +- Metrics export (Prometheus, Application Insights, etc.) + +### Step 7: Generate Service Communication Sequence Section + +Create a **Mermaid `sequenceDiagram`** and produce the complete `## Service Communication Sequence` section: +- Show key actors: Client, API Gateway (if present), Controllers, Services, External Services, Message Brokers +- Annotate synchronous calls with solid arrows and asynchronous calls with dashed arrows +- Include request/response types where relevant +- Show error handling paths for critical flows (circuit breaker, retry) +- For gateway aggregation flows, show how multiple downstream calls are composed + +Example: + +~~~mermaid +sequenceDiagram + participant Client + participant Gateway as "API Gateway" + participant CustSvc as "Customers Service" + participant VisitSvc as "Visits Service" + participant DB as "Database" + + Client->>Gateway: GET /api/gateway/owners/1 + Gateway->>CustSvc: GET /owners/1 + CustSvc->>DB: findById(1) + DB-->>CustSvc: Owner + Pets + CustSvc-->>Gateway: OwnerDetails(pets=[Pet1,Pet2]) + Gateway->>VisitSvc: GET /pets/visits?petId=1,2 + alt Visits Service Available + VisitSvc->>DB: findByPetIdIn([1,2]) + DB-->>VisitSvc: Visits list + VisitSvc-->>Gateway: Visits(items=[...]) + else Circuit Breaker Open + Gateway-->>Gateway: Fallback - empty visits + end + Gateway->>Gateway: Merge visits into pets + Gateway-->>Client: 200 OwnerDetails + Visits +~~~ + +### Step 8: Save Output + +Save to `.github/modernize/assessment/engines/facts/api-service-contracts.md` with this exact structure: + +``` +# API & Service Communication Contracts + +A brief introduction (1-2 sentences) summarizing the API surface and communication patterns found. + +## Service Catalog + +[Table: Service | Port | Category | Purpose] + +## API Endpoints Inventory + +[Table: Service | Method | Path | Request Type | Response Type] + +## Management & Observability Endpoints + +[Table: Service | Endpoint | Custom Metrics (if any)] + +## DTOs & Contracts + +[Description of gateway-level DTOs vs service-level entities, immutability, serialization] + +## Communication Patterns + +[Description of sync/async patterns, gateway aggregation/composition logic, circuit breaker/retry policies with timeout values, service discovery, startup dependency chain, and security posture (authentication/authorization/TLS — or explicit statement that none is configured)] + +## Service Technology Matrix + +[Table: Service | Web | Data Access | Discovery | Gateway | Actuator | Cache | Metrics] + +## Service Communication Sequence + +< Mermaid sequenceDiagram here > +``` + +## Scaling Rules + +- If the project has **more than 30 endpoints**, group by service/controller and show representative endpoints per group +- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module communication in the sequence diagram and list all endpoints in the table +- Aggregate similar endpoints (e.g., CRUD operations on the same resource) into one table row if needed for brevity +- For the service technology matrix, use checkmarks or short labels; omit columns where no service uses the capability + +## Mermaid Syntax Rules + +The diagram must parse cleanly under **Mermaid >= 9.x**. Anything outside the legal subset crashes the entire diagram with `Syntax error in text`. + +- Use `sequenceDiagram` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels +- Use `->>` for synchronous calls and `-->>` for responses/async messages +- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` +- Use `alt`/`else`/`end` blocks to show circuit breaker fallback paths +- Do not use backticks inside node labels + +### Line breaks — HARD RULE + +- **NEVER use `\n` for line breaks inside participant aliases, messages, or notes.** The literal `\n` escape was removed in modern Mermaid and triggers "Syntax error in text". +- In participant aliases: keep them on a single line, e.g. `participant Svc as "Order Service"` — not `"Order\nService"`. +- In `Note over` / `Note right of`: keep the note on one line, or split into multiple `Note` statements. +- In message arrow labels: keep concise; if you need multiple facts, split into multiple arrows. +- ❌ `participant API as "REST API\n(SubsonicController)"` +- ✅ `participant API as "REST API (SubsonicController)"` + +### Self-check before emitting each ```mermaid block + +1. Search the block for the two characters `\n` — remove or split the line. Zero `\n` must remain. +2. Confirm every `alt`/`opt`/`loop`/`par` block is closed by `end`. +3. Confirm every quoted alias is on a single line. + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No API endpoints found**: Output: `> ERROR: No recognized API endpoints found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some endpoints or communication patterns could not be fully identified.` + +## Success Criteria + +- Service catalog table lists all discovered services with ports, categories, and purposes +- API endpoints table lists all discovered endpoints with HTTP method, path, and types +- Management/observability endpoints are cataloged with custom metric names +- Gateway aggregation/composition patterns are documented with fallback behavior +- Service technology matrix shows per-service capabilities +- Communication patterns section describes sync/async patterns, resilience policies, and security posture (authentication, authorization, TLS — explicitly stating if none is configured) +- Mermaid sequence diagram renders correctly showing primary request flow with aggregation and fallback +- File saved to `.github/modernize/assessment/engines/facts/api-service-contracts.md` diff --git a/plugins/github-copilot-modernization/skills/architecture-diagram/SKILL.md b/plugins/github-copilot-modernization/skills/architecture-diagram/SKILL.md new file mode 100644 index 0000000..dffa82d --- /dev/null +++ b/plugins/github-copilot-modernization/skills/architecture-diagram/SKILL.md @@ -0,0 +1,207 @@ +--- +name: architecture-diagram +description: Generate architecture diagram with component relationship details from project analysis +--- + +# Architecture Diagram + +This skill generates a two-layer architecture visualization: a high-level application architecture diagram and a detailed component relationship diagram. Produce both in a single pass and save to `.github/modernize/assessment/engines/facts/architecture-diagram.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Execution Steps + +### Step 1: Generate Application Architecture Section + +Analyze the project and produce the complete `## Application Architecture` section in one pass: + +**Analysis:** +- Examine build files (Java: pom.xml, build.gradle; .NET: *.csproj, *.sln; JS/TS: package.json, tsconfig.json) +- Review configuration files (application.properties, appsettings.json, .env, database/API configs) +- Scan key source files to extract: framework, major dependencies, data access patterns, external integrations, technology stack +- Identify application layers (UI, Business Logic, Data Access), data storage technologies, and external service dependencies + +**Diagram — Mermaid `flowchart TD`:** +- Application layers with technology info (use `subgraph` for grouping) +- Data storage components (specific names like "PostgreSQL", "Redis") +- External service integrations +- Data flow with descriptive arrow labels + +**Do NOT include**: individual classes/methods or migration directions. + +Example: + +~~~mermaid +flowchart TD + subgraph Client["Client Layer"] + Browser["Web Browser"] + end + subgraph App["Application Layer - Spring Boot 2.7"] + Web["Spring MVC + Thymeleaf"] + Security["Spring Security"] + Service["Business Services"] + end + subgraph Data["Data Layer"] + JPA["Spring Data JPA"] + DB[("PostgreSQL 14")] + Cache[("Redis")] + end + subgraph External["External Services"] + SMTP["SMTP Email Service"] + S3["AWS S3 Storage"] + end + + Browser -->|"HTTP requests"| Web + Web --> Security -->|"authorized"| Service + Service -->|"CRUD operations"| JPA + JPA -->|"SQL queries"| DB + Service -->|"session cache"| Cache + Service -->|"send email"| SMTP + Service -->|"file upload"| S3 +~~~ + +**Textual explanations (write immediately after the diagram):** +- **Technology Stack Summary table**: Layer | Technology | Version | Purpose (e.g., Presentation | ASP.NET MVC 5 | 5.2.7 | Server-side web framework) +- **Data Storage & External Services**: A short paragraph describing what databases, caches, message brokers, or external APIs are used and how they fit into the architecture +- **Key Architectural Decisions**: 1-3 bullet points on notable patterns (e.g., "Uses repository pattern with EF6 for data access", "Autofac provides DI with module-based registration") + +### Step 2: Generate Component Relationships Section + +Analyze component interactions and produce the complete `## Component Relationships` section in one pass: + +**Analysis:** +- Identify key component types by framework conventions: + - Java (Spring): Controllers, Services, Repositories, Configurations, Entities, DTOs, Listeners, Filters + - Java (Jakarta EE): Servlets, EJBs, CDI Beans, JPA Entities, JAX-RS Resources + - .NET (ASP.NET Core): Controllers, Services, Middleware, DbContext, Entities, Hubs, Filters + - .NET (Blazor/MVC): Pages, Components, ViewModels + - JavaScript/TypeScript (Node.js): Routes, Controllers, Services, Middleware, Models + - JavaScript/TypeScript (React/Angular/Vue): Components, Hooks, Services, Stores, Pages +- Trace dependency injection (constructor/field injection) +- Map communication patterns (REST, gRPC, message queues, events) +- Map data access patterns (service-to-repository, DbContext usage) +- Detect cross-cutting concerns (middleware, interceptors, filters) + +**Diagram — Mermaid `flowchart LR`:** +- Components grouped by architectural layer using `subgraph` (Presentation, Business Logic, Data Access, Infrastructure) +- Interaction arrows with brief labels +- Cross-cutting concerns + +**Do NOT include**: method signatures, private helpers, or external dependencies (covered by dependency-map skill). + +Example: + +~~~mermaid +flowchart LR + subgraph Presentation + UserCtrl["UserController"] + OrderCtrl["OrderController"] + end + subgraph Business["Business Logic"] + UserSvc["UserService"] + OrderSvc["OrderService"] + NotifSvc["NotificationService"] + end + subgraph DataAccess["Data Access"] + UserRepo["UserRepository"] + OrderRepo["OrderRepository"] + end + subgraph Infra["Infrastructure"] + AuthFilter["AuthenticationFilter"] + LogMiddleware["LoggingMiddleware"] + end + + UserCtrl -->|"delegates"| UserSvc + OrderCtrl -->|"delegates"| OrderSvc + OrderSvc -->|"lookups"| UserSvc + OrderSvc -->|"triggers"| NotifSvc + UserSvc -->|"queries"| UserRepo + OrderSvc -->|"queries"| OrderRepo + AuthFilter -.->|"intercepts"| UserCtrl + AuthFilter -.->|"intercepts"| OrderCtrl + LogMiddleware -.->|"wraps"| Presentation +~~~ + +**Textual explanation (write immediately after the diagram):** +- **Component Inventory table**: Component | Layer | Type | Responsibility (e.g., CatalogController | Presentation | MVC Controller | Handles catalog browsing and CRUD) + +### Step 3: Save Output + +Save the combined output to `.github/modernize/assessment/engines/facts/architecture-diagram.md` with this exact structure: + +``` +# Architecture Diagram + +A brief introduction (1-2 sentences). + +## Application Architecture + +< Layer 1 Mermaid flowchart TD here > + +### Technology Stack Summary + +[Table: Layer | Technology | Version | Purpose] + +### Data Storage & External Services + +[Short paragraph on databases, caches, external APIs] + +### Key Architectural Decisions + +[1-3 bullet points on notable patterns] + +## Component Relationships + +< Layer 2 Mermaid flowchart LR here > + +### Component Inventory + +[Table: Component | Layer | Type | Responsibility] +``` + +## Scaling Rules + +- If the project has **more than 30 components**, aggregate by package/namespace (e.g., show `com.example.orders` as one node instead of listing every class) +- Keep each diagram under **40 nodes** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module boundaries in Layer 1 and key components within the most important modules in Layer 2 + +## Mermaid Syntax Rules + +The diagram must parse cleanly under **Mermaid >= 9.x** (the version used by GitHub, VS Code, Obsidian, and every modern renderer). Anything outside the legal subset crashes the entire diagram with `Syntax error in text`, not just the offending line. + +- Use `flowchart TD` for Layer 1 and `flowchart LR` for Layer 2 +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text +- Always quote arrow labels with double quotes: `-->|"label"|` +- Use `subgraph` for grouping, with a display name in quotes if it contains spaces +- Verify all node IDs are unique across the entire diagram + +### Line breaks in node labels — HARD RULE + +- **NEVER use `\n` for line breaks inside node labels.** The literal `\n` escape was removed in modern Mermaid and is the #1 cause of "Syntax error in text" — every node containing `\n` will fail to render. +- **Use `
` instead** for an explicit line break: `Node["First line
Second line"]`. +- If a label is long, prefer a single concise phrase over multi-line. Move details into the Component Inventory / Technology Stack tables that follow the diagram. +- ❌ `MediaLib["Media Library\n(MediaScannerService\nMediaFileService)"]` +- ✅ `MediaLib["Media Library
MediaScannerService
MediaFileService"]` +- ✅ `MediaLib["Media Library"]` (and list the sub-components in the inventory table) + +### Self-check before emitting each ```mermaid block + +1. Search the block for the two characters `\n` — if found, replace each with `
` (or remove). Zero `\n` must remain. +2. Confirm every node ID is unique and every `subgraph` is closed by `end`. +3. Confirm every arrow label is double-quoted. + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No source code found**: Output: `> ERROR: No recognized source files found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some components could not be identified"]` + +## Success Criteria + +- Layer 1 Mermaid diagram renders correctly showing architecture with technology names, data storage, and external dependencies +- Layer 1 is accompanied by Technology Stack Summary table, Data Storage & External Services paragraph, and Key Architectural Decisions +- Layer 2 Mermaid diagram renders correctly showing component interactions grouped by architectural layer +- Layer 2 is accompanied by Component Inventory table +- File saved to `.github/modernize/assessment/engines/facts/architecture-diagram.md` diff --git a/plugins/github-copilot-modernization/skills/assessment/SKILL.md b/plugins/github-copilot-modernization/skills/assessment/SKILL.md index 4bb64ed..a8b236f 100644 --- a/plugins/github-copilot-modernization/skills/assessment/SKILL.md +++ b/plugins/github-copilot-modernization/skills/assessment/SKILL.md @@ -5,13 +5,18 @@ description: Run application assessment for a single repository # Application Assessment -This skill performs application assessment for a single repository using AppCAT tools. +This skill performs application assessment for a single repository. It supports Java, .NET, and JavaScript/TypeScript projects. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to assess. Defaults to the current directory (repository root) when not specified. All assessment outputs are written relative to this path (e.g. `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json`). For a repository with multiple sub-projects, pass the sub-project directory path so that each sub-project's outputs are isolated. ## When to Use This Skill Use this skill when you need to: - Assess a Java or .NET application for cloud readiness and migration issues +- Assess a JavaScript/TypeScript project for outdated dependencies and available updates - Generate detailed assessment reports with issue analysis and recommendations - Understand application dependencies, frameworks, and potential migration blockers @@ -20,61 +25,77 @@ Use this skill when you need to: This skill performs a simplified assessment workflow: 1. **Check Project Type and Prerequisites**: - - **For Java projects**: Verify that MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') - - If these MCP tools are not configured, return immediately with setup instructions + - **For Java projects**: Check MCP tool availability in this order: + 1. **Primary**: Check if 'appmod-run-assessment-action' MCP tool is available + - If available, use ONLY this tool. It handles everything (prerequisite checks, installation, and assessment execution) in a single call. + - Do NOT call any other assessment MCP tools when this tool is available. + 2. **Fallback**: If 'appmod-run-assessment-action' is NOT available, check if 'appmod-precheck-assessment' MCP tool is available + - If available, use the legacy workflow: call 'appmod-precheck-assessment' first, then follow its guidance for 'appmod-install-appcat' and 'appmod-run-assessment'. + 3. If neither tool is configured, return immediately with setup instructions. - **For .NET projects**: Check if .NET SDK is available - No MCP tools required for .NET assessment + - **For JavaScript/TypeScript projects**: Check if Node.js and npm are available + - No MCP tools required for JS/TS assessment -2. **Clean Previous Assessment Data**: - - Remove files in `.github/modernize/assessment` folder to prevent interference with the new assessment - - This ensures a clean state before running the assessment - -3. **Run Assessment**: +2. **Run Assessment**: - **For Java projects**: Trigger AppCAT analysis via Assessment MCP server - - Uses 'appmod-precheck-assessment' and 'appmod-run-assessment' MCP tools - - **Must specify domain**: Pass `domain` parameter as "Java Upgrade" or "Migrate to Azure" or both - - Example: `appmod-run-assessment --domain "Java Upgrade" --projectPath /path/to/project` - - Example: `appmod-run-assessment --domain "Migrate to Azure" --projectPath /path/to/project` - - Auto-detects project configuration + - **If 'appmod-run-assessment-action' is available (primary path)**: + - Call 'appmod-run-assessment-action' MCP tool only + - The MCP tool automatically saves the report to the versioned directory + - **If falling back to 'appmod-precheck-assessment' (legacy path)**: + - Call 'appmod-precheck-assessment' to check prerequisites + - Call 'appmod-install-appcat' to install AppCAT if needed + - Call 'appmod-run-assessment' to run the assessment - **For .NET projects**: Install and run AppCAT directly - Install: `dotnet tool update dotnet-appcat` - - Find all .csproj files in the workspace + - Find all .csproj files under `{workspace-path}` - Join project paths with semicolons: `projectPaths="project1.csproj;project2.csproj"` - - Run: `dotnet-appcat analyze $projectPaths --source Solution --target Any --serializer APPMODJSON --code --privacyMode Restricted --non-interactive --report {workspace-path}\.github\modernize\assessment\report.json` - - Analyzes code for cloud migration issues + - Run: `appcat analyze $projectPaths --source Solution --target Any --serializer APPMODJSON --code --privacyMode Restricted --non-interactive --report {workspace-path}\.github\modernize\appcat\result\report.json` + - **For JavaScript/TypeScript projects**: Install and run npm-check-updates + - Install: `npm install -g npm-check-updates@19.6.3 --prefix {tool-install-dir}` + - Run: `ncu --format group --packageFile {workspace-path}/package.json` + - Generate the `reportId` as a UTC timestamp formatted as `yyyyMMddHHmmss` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) + - Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` + - Save the output to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` + - Do NOT save a copy to the top-level assessment directory + - Analyzes code for cloud migration issues or dependency updates - Generates structured assessment data - - Report is stored under `.github/modernize/assessment/` directory - -4. **Consolidate Report** (Java projects only): - - Search for `report.json` under `.github/modernize/assessment/` subdirectories - - Common locations: `.github/modernize/assessment/result/report.json` - - Copy the latest report to `.github/modernize/assessment/report.json` - - For .NET projects, the report is already generated at `.github/modernize/assessment/report.json` - - This consolidated report should be included in the pull request -## Input Parameters - -- `workspace-path` (required): Path to the project to assess -- `domain` (required for Java projects): Assessment domain(s) - - For Java projects: Must specify one or both of: - - `"Java Upgrade"` - For Java version and framework upgrade assessment - - `"Migrate to Azure"` - For Azure migration readiness assessment - - Both domains can be specified: `["Java Upgrade", "Migrate to Azure"]` - - For .NET projects: This parameter is not used (automatically handles all assessment types) +3. **Save Report to Versioned Directory (All languages)**: + - **For Java projects (primary path — 'appmod-run-assessment-action')**: The MCP tool automatically saves the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` — no manual saving needed + - **For Java projects (legacy fallback path — 'appmod-precheck-assessment')**: + 1. Find `report.json` under `{workspace-path}/.github/modernize/appcat/result/` + 2. Read the report and extract `metadata.analysisStartTime` + 3. Format the timestamp as `yyyyMMddHHmmss` to produce the `reportId` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) + 4. Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` + 5. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + - **For .NET projects**: + 1. Find `report.json` at `{workspace-path}/.github/modernize/appcat/result/report.json` + 2. Read the report and extract `metadata.analysisStartTime` + 3. Format the timestamp as `yyyyMMddHHmmss` to produce the `reportId` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) + 4. Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` + 5. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + - This versioned report should be included in the pull request ## How to Use ### Prerequisites **For Java projects**: -- MCP tools must be available: 'appmod-precheck-assessment' and 'appmod-run-assessment' -- If tools are not configured, the skill will return instructions for setup +- **Primary**: MCP tool 'appmod-run-assessment-action' — preferred, handles everything in one call +- **Fallback**: If primary tool is not available, use 'appmod-precheck-assessment' → 'appmod-install-appcat' → 'appmod-run-assessment' workflow +- If neither tool is configured, the skill will return instructions for setup **For .NET projects**: - .NET SDK must be installed - No MCP tools required - appcat will be installed and run directly via .NET CLI - The assessment will automatically install `dotnet-appcat` tool if not already present +**For JavaScript/TypeScript projects**: +- Node.js and npm must be installed +- No MCP tools required - npm-check-updates will be installed and run directly via npm +- The assessment will automatically install `npm-check-updates` if not already present + ### Triggering Assessment Simply express the intent to assess the application. Example prompts: @@ -83,75 +104,94 @@ Simply express the intent to assess the application. Example prompts: - "Run assessment for this project" The assessment process automatically: -- Detects project language and framework -- **For Java**: - - Uses MCP tools to install and run AppCAT - - **Requires domain specification**: You must specify which assessment domain(s) to run: - - `"Java Upgrade"` - Analyzes Java version upgrade paths, Spring Boot versions, deprecated APIs - - `"Migrate to Azure"` - Analyzes Azure migration readiness, service recommendations - - Both domains can be run sequentially by specifying both - - Example: `appmod-run-assessment` with domain parameter set to `"Java Upgrade"` or `"Migrate to Azure"` +- Detects project language and framework within `{workspace-path}` +- **For Java**: Uses MCP tool to run AppCAT and automatically save report to versioned directory - **For .NET**: Installs dotnet-appcat tool and runs analysis directly +- **For JavaScript/TypeScript**: Installs npm-check-updates and runs dependency analysis - Executes comprehensive analysis -- Generates report at `.github/modernize/assessment/report.json` - -### Report Consolidation +- **For Java (primary)**: Report is automatically saved to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +- **For Java (legacy fallback)**: Generates report at `{workspace-path}/.github/modernize/appcat/result/`, then moved to versioned directory +- **For .NET**: Generates report at `{workspace-path}/.github/modernize/appcat/result/report.json` +- **For JavaScript/TypeScript**: Generates report at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` +### Report Saving **For Java projects**: -1. Search for `report.json` files under `.github/modernize/assessment/` subdirectories -2. If multiple reports exist, identify the most recently modified one -3. Copy the latest report to `.github/modernize/assessment/report.json` -4. Include this consolidated report in the pull request +1. **If using 'appmod-run-assessment-action' (primary path)**: The MCP tool automatically saves the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` — no manual report moving is needed +2. **If using legacy fallback path ('appmod-precheck-assessment')**: + - Find `report.json` under `{workspace-path}/.github/modernize/appcat/result/` + - Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` + - Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +3. Include this versioned report in the pull request **For .NET projects**: -1. Report is directly generated at `.github/modernize/assessment/report.json` -2. Include this report in the pull request +1. Report is initially generated at `{workspace-path}/.github/modernize/appcat/result/report.json` +2. Read the report and extract `metadata.analysisStartTime`, format as `yyyyMMddHHmmss` to get `reportId` +3. Move the report to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +4. Include this versioned report in the pull request + +**For JavaScript/TypeScript projects**: +1. Generate the `reportId` as a UTC timestamp formatted as `yyyyMMddHHmmss` (e.g. `2024-06-15T14:30:52Z` becomes `20240615143052`) +2. Create the versioned directory: `mkdir -p {workspace-path}/.github/modernize/assessment/reports/report-{reportId}` +3. Save the ncu output to `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` +4. Include this versioned report in the pull request ## Report Output Location Report location depends on project type: **For Java projects** (via MCP server): -- Initially stored under `.github/modernize/assessment/` subdirectories -- Common locations: `.github/modernize/assessment/result/report.json` -- Consolidated to: `.github/modernize/assessment/report.json` +- **Primary path ('appmod-run-assessment-action')**: Automatically saved to: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +- **Legacy fallback path ('appmod-precheck-assessment')**: Initially stored under `{workspace-path}/.github/modernize/appcat/result/`, then moved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` **For .NET projects** (direct execution): -- Directly generated at: `.github/modernize/assessment/report.json` +- Initially generated at: `{workspace-path}/.github/modernize/appcat/result/report.json` +- Moved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` + +**For JavaScript/TypeScript projects** (direct execution): +- Saved to versioned directory: `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` -Final report location (include this in pull request): -- `.github/modernize/assessment/report.json` ## Success Criteria Assessment is complete when: - ✅ **For Java**: MCP server is available (or clear instructions provided if not) - ✅ **For .NET**: .NET SDK is available and dotnet-appcat tool is installed -- ✅ AppCAT analysis executes without errors -- ✅ Report generated at `.github/modernize/assessment/report.json` +- ✅ **For JavaScript/TypeScript**: Node.js and npm are available and npm-check-updates is installed +- ✅ AppCAT analysis executes without errors (Java/.NET) or ncu analysis executes without errors (JS/TS) +- ✅ **For Java and .NET**: Report generated at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/report.json` +- ✅ **For JavaScript/TypeScript**: Report generated at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` - ✅ Report metadata includes assessment tool version, timestamp, and configuration ## Troubleshooting **Prerequisites Not Met**: -- **For Java**: Verify MCP tools are available ('appmod-precheck-assessment' and 'appmod-run-assessment') - - Return immediately with setup instructions if tools are not available +- **For Java**: First check for 'appmod-run-assessment-action', then fall back to 'appmod-precheck-assessment' + - Return immediately with setup instructions if neither tool is available - Do not attempt to run assessment without MCP - **For .NET**: Verify .NET SDK is installed - Check with `dotnet --version` command - Provide installation instructions if .NET SDK is missing +- **For JavaScript/TypeScript**: Verify Node.js and npm are installed + - Check with `npm --version` command + - Provide installation instructions if npm is missing **Assessment Failures**: -- Unsupported project type (only Java and .NET supported) +- Unsupported project type (only Java, .NET, and JavaScript/TypeScript supported) - **For Java**: MCP server communication errors -- **For .NET**: +- **For .NET**: - dotnet-appcat tool installation failure - - dotnet-appcat command execution errors + - appcat command execution errors +- **For JavaScript/TypeScript**: + - npm-check-updates installation failure + - ncu command execution errors + - No package.json found at `{workspace-path}/package.json` - Invalid project structure or build configuration **Report Generation Issues**: -- **For Java**: No report.json found under `.github/modernize/assessment/` subdirectories after MCP execution -- **For .NET**: Report not generated at `.github/modernize/assessment/report.json` -- Report file is corrupted or invalid JSON +- **For Java (primary)**: No report.json found under `{workspace-path}/.github/modernize/assessment/reports/report-*/report.json` after MCP execution +- **For Java (legacy fallback)**: No report.json found under `{workspace-path}/.github/modernize/appcat/result/` after MCP execution +- **For .NET**: Report not generated at `{workspace-path}/.github/modernize/appcat/result/report.json`, or `metadata.analysisStartTime` missing from report +- **For JavaScript/TypeScript**: Report not generated at `{workspace-path}/.github/modernize/assessment/reports/report-{reportId}/js-assessment-report.md` +- Report file is corrupted or invalid JSON (Java/.NET only) For any failure, provide clear error messages and troubleshooting steps. diff --git a/plugins/github-copilot-modernization/skills/business-workflows/SKILL.md b/plugins/github-copilot-modernization/skills/business-workflows/SKILL.md new file mode 100644 index 0000000..9a4b01e --- /dev/null +++ b/plugins/github-copilot-modernization/skills/business-workflows/SKILL.md @@ -0,0 +1,214 @@ +--- +name: business-workflows +description: Generate core business workflow documentation with sequence diagram +--- + +# Core Business Workflows + +Analyze the project to document business processes end-to-end, domain entities, business rules, service-to-domain mapping, cross-service data flows, and decision logic. Generate a Mermaid sequence diagram showing the primary business workflow. Save to `.github/modernize/assessment/engines/facts/business-workflows.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the business domain (what the application does for its users). Do NOT restate the technology stack, database options, or framework versions. +- **Domain Entities table**: Focus on business meaning — entity description, bounded context, and business relationships. Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill. +- **Validation rules in workflow steps**: When describing a workflow step that involves validation, reference the rule by name (e.g., "PetValidator checks name and birthDate") rather than re-listing every constraint. Enumerate the full validation rules only once in the "Business Rules & Decision Logic" section. +- **Caching behavior**: If caching affects a workflow (e.g., vet list served from cache), mention the business impact (e.g., "vet data served from cache, reducing load") but do NOT describe the cache provider, TTL, configuration class, or JMX statistics — those are owned by the `data-architecture` skill. +- **API endpoint paths and HTTP methods**: Only mention endpoint paths as entry points for workflows (e.g., "Staff submits POST /owners/new"). Do NOT create endpoint inventory tables — those are owned by the `api-service-contracts` skill. + +## Execution Steps + +### Step 1: Generate Domain Entities Section + +Identify the domain model and produce the complete `## Domain Entities` section: + +- Identify domain entities and aggregates (DDD patterns if present) +- Focus on business meaning — entity description, bounded context, and business relationships +- Do NOT reproduce entity field lists, data types, PK/FK annotations, or ORM mapping details (cascade, fetch strategy) — those are owned by the `data-architecture` skill + +### Step 2: Generate Service-to-Domain Mapping Section + +Map each service to its bounded context and owned entities, then produce the complete `## Service-to-Domain Mapping` section (applies to microservice or multi-module architectures): + +- Service name → bounded context (e.g., `customers-service` → Customer Management, `visits-service` → Appointment Management) +- Domain entities owned by each service/context +- Cross-context data exchange patterns: how domains communicate (REST API, events, shared database) +- Data that spans contexts (e.g., `petId` as a foreign key in visits-service referencing customers-service's Pet entity) +- Aggregation boundaries: which service is the source of truth for which data + +### Step 3: Generate Primary Workflows Section + +Scan for business process entry points, trace each significant workflow end-to-end, and produce the complete `## Primary Workflows` section: + +**Entry points to scan:** +- Controllers/endpoints that initiate business processes (not just CRUD — look for multi-step operations) +- **API Gateway aggregation endpoints** that compose responses from multiple backend services — these are business workflow entry points even though they live in the gateway layer (e.g., fetching owner details combined with visit history) +- Scheduled tasks (`@Scheduled`, Quartz, Hangfire, cron jobs, `BackgroundService`) +- Event listeners (`@EventListener`, `@KafkaListener`, `INotificationHandler`, message handlers) +- CLI commands or batch job entry points +- Startup/initialization routines that set up business state + +**For each significant entry point, trace the flow:** +- Entry point → service layer → domain logic → persistence +- The sequence of operations: validation → business rule check → state mutation → side effects +- Branching logic (if/else, switch, strategy pattern) that represents business decisions +- Orchestration vs choreography patterns in multi-service workflows + +### Step 4: Generate Cross-Service Data Flows Section + +Trace cross-service data composition flows end-to-end and produce the complete `## Cross-Service Data Flows` section: + +- Gateway aggregation patterns: e.g., gateway fetches owner from customers-service → extracts pet IDs → fetches visits from visits-service → merges visits into pet records → returns composite response +- Which service provides which data and how they are joined/merged +- Circuit breaker fallback behavior that affects business outcomes (e.g., "when visits-service is unavailable, owner details are returned without visit history" — this is a business-relevant degradation, not just a technical detail) + +### Step 5: Generate Business Workflow Sequence Section + +Create a **Mermaid `sequenceDiagram`** showing the primary business workflow end-to-end and produce the complete `## Business Workflow Sequence` section: + +- Show the most important business process (e.g., "customer places order", "owner registers pet and schedules visit", "gateway aggregates owner with visit history") +- Include actors, services, and domain entities as participants +- Show business rule checks and decision points +- Annotate with business-relevant labels (not technical method names) +- Use `alt`/`else` blocks to show circuit breaker fallback paths that affect business outcomes +- Show cross-service data aggregation flows + +Example: + +~~~mermaid +sequenceDiagram + participant Owner + participant Gateway as "API Gateway" + participant CustSvc as "Customer Service" + participant VisitSvc as "Visit Service" + participant DB as "Database" + + Owner->>Gateway: View my pets and visits + Gateway->>CustSvc: Get owner details + CustSvc->>DB: Find owner with pets + DB-->>CustSvc: Owner + Pet list + CustSvc-->>Gateway: OwnerDetails(pets) + + Gateway->>Gateway: Extract pet IDs from response + Gateway->>VisitSvc: Get visits for pets (batch) + alt Visit Service Available + VisitSvc->>DB: Find visits by pet IDs + DB-->>VisitSvc: Visit records + VisitSvc-->>Gateway: Visits per pet + Gateway->>Gateway: Merge visits into pet records + else Visit Service Unavailable (Circuit Breaker) + Note over Gateway: Fallback - return owner without visits + end + Gateway-->>Owner: Complete owner profile with visits +~~~ + +### Step 6: Generate Business Rules & Decision Logic Section + +Extract and document business rules and cross-cutting concerns, and produce the complete `## Business Rules & Decision Logic` section: + +**Business Rules:** +- **Validation rules**: Input validation, field constraints, format checks, custom validators +- **Decision logic**: Conditional business logic, pricing rules, eligibility checks, approval workflows +- **State transitions**: Entity lifecycle states (e.g., Order: Created → Confirmed → Shipped → Delivered), state machines +- **Business constraints**: Uniqueness rules, capacity limits, temporal constraints (booking windows, cooldown periods) +- **Computed values**: Derived fields, calculated totals, aggregated metrics +- **Data integrity rules**: Bidirectional relationship maintenance (e.g., `owner.addPet(pet)` ensuring both sides of the relationship are set) + +**Cross-Cutting Concerns:** +- **Transactions**: Transaction boundaries, `@Transactional` scope, saga patterns, eventual consistency +- **Error handling**: Business exception types, compensating actions, dead-letter handling +- **Audit/logging**: Business event logging, audit trails, change tracking +- **Authorization**: Business-level authorization rules (role-based, attribute-based, resource ownership) + +### Step 7: Save Output + +Save to `.github/modernize/assessment/engines/facts/business-workflows.md` with this exact structure: + +``` +# Core Business Workflows + +A brief introduction (1-2 sentences) summarizing the application's business domain. + +## Domain Entities + +[Table: Entity | Service / Bounded Context | Description | Key Relationships] + +## Service-to-Domain Mapping + +[Table: Service | Domain Context | Owned Entities | External Dependencies] + +## Primary Workflows + +### Workflow 1: [Name] + +[Description, steps, business rules involved, cross-service interactions] + +### Workflow 2: [Name] + +[Description, steps, business rules involved] + +## Cross-Service Data Flows + +[Description of aggregation/composition patterns, which service provides which data, how data is joined, fallback behavior when services are unavailable] + +## Business Workflow Sequence + +< Mermaid sequenceDiagram here, with alt/else blocks for fallback paths > + +## Business Rules & Decision Logic + +[Summary of key business rules, validation rules, state transitions, and decision points] +``` + +## Scaling Rules + +- If the project has **more than 10 distinct workflows**, focus on the 3-5 most important business processes and summarize the rest in a "Other Workflows" section +- Keep the sequence diagram under **40 participants and messages** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on the primary end-to-end business workflow that spans modules +- Aggregate minor CRUD operations and show only workflows that involve business logic beyond simple create/read/update/delete + +## Mermaid Syntax Rules + +The diagram must parse cleanly under **Mermaid >= 9.x**. Anything outside the legal subset crashes the entire diagram with `Syntax error in text`. + +- Use `sequenceDiagram` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in participant labels — use plain text or quoted labels +- Use `->>` for synchronous calls and `-->>` for responses +- Use `participant` with alias syntax for readable labels: `participant Svc as "OrderService"` +- Use `Note over` for annotations about business decisions or fallback behavior +- Use `alt`/`else`/`end` blocks for decision points and circuit breaker fallbacks +- Do not use backticks inside participant labels + +### Line breaks — HARD RULE + +- **NEVER use `\n` for line breaks inside participant aliases, messages, or notes.** The literal `\n` escape was removed in modern Mermaid and triggers "Syntax error in text". +- Keep aliases on a single line: `participant Tx as "Transcoding Service"` — not `"Transcoding\nService"`. +- For multi-fact notes, emit multiple `Note over` statements instead of `\n`-separated text. +- ❌ `Note over Client,API: First fact\nSecond fact` +- ✅ Two consecutive `Note over Client,API: ...` lines. + +### Self-check before emitting each ```mermaid block + +1. Search the block for the two characters `\n` — remove or split. Zero `\n` must remain. +2. Confirm every `alt`/`opt`/`loop`/`par` block is closed by `end`. + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No business logic found**: Output: `> ERROR: No recognized business logic or workflows found at {workspace-path}. The project may be a library or framework without business processes.` +- **Insufficient info**: Generate a best-effort document from available data. Add a note: `> Note: Some workflows or business rules could not be fully traced.` + +## Success Criteria + +- Domain entities table lists key entities with their owning service/bounded context, descriptions, and relationships +- Service-to-domain mapping table maps each service to its domain context and owned entities +- At least one primary workflow is documented with steps, business rules, and cross-service interactions +- Cross-service data flows describe aggregation/composition patterns with fallback behavior +- Mermaid sequence diagram renders correctly showing end-to-end business workflow with `alt`/`else` blocks for fallbacks +- Business rules section summarizes validation, decision logic, state transitions, and constraints +- File saved to `.github/modernize/assessment/engines/facts/business-workflows.md` diff --git a/plugins/github-copilot-modernization/skills/configuration-inventory/SKILL.md b/plugins/github-copilot-modernization/skills/configuration-inventory/SKILL.md new file mode 100644 index 0000000..0c12ac8 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/configuration-inventory/SKILL.md @@ -0,0 +1,205 @@ +--- +name: configuration-inventory +description: Generate comprehensive configuration and externalized settings inventory +--- + +# Configuration & Externalized Settings Inventory + +Analyze the project to produce a comprehensive inventory of all configuration sources, build profiles, runtime profiles, externalized properties, secrets workflows, feature flags, startup dependencies, and framework versions. Save to `.github/modernize/assessment/engines/facts/configuration-inventory.md`. + +> Note: This skill produces a comprehensive reference document. For structured findings suitable for automated processing, see `fact-profile-settings`, `fact-environment-variables`, and `fact-xml-configs`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the configuration landscape (number of config sources, profiles, secrets approach). Do NOT restate the application's architecture type, business domain, or API surface. +- **Database architecture details** (entity models, ER diagrams, ORM mappings, caching strategy rationale, repository methods) are owned by the `data-architecture` skill. In the Properties Inventory, list database-related property keys and values as raw configuration entries, but do NOT explain their behavioral implications (e.g., do not explain what `spring.jpa.open-in-view=false` means for lazy loading — that belongs in `data-architecture.md`). +- **API endpoints** are owned by the `api-service-contracts` skill. Do NOT list HTTP endpoints, controller routes, or actuator paths. +- **Business workflows and validation rules** are owned by the `business-workflows` skill. Do NOT describe business processes or entity validation constraints. +- **Entity/domain model listings** are owned by `data-architecture` and `business-workflows`. Do NOT enumerate entity names, fields, or relationships. + +## Execution Steps + +### Step 1: Generate Configuration Sources Section + +Identify all configuration files and sources and produce the complete `## Configuration Sources` section: + +- Java (Spring): `application.properties`, `application.yml`, `bootstrap.properties`, `bootstrap.yml` — note that `bootstrap.*` files are distinct from `application.*` (bootstrap configures the config server connection and runs before application context; application configures the app itself) +- .NET: `appsettings.json`, `appsettings.{Environment}.json`, `web.config`, `launchSettings.json` +- JavaScript/TypeScript: `.env`, `.env.local`, `.env.production`, `config/*.js`, `config/*.ts` +- Shared: `docker-compose.yml` environment sections, Kubernetes ConfigMaps/Secrets YAML files +- Config server references: Spring Cloud Config (note the external Git repository URI), Azure App Configuration, AWS AppConfig, Consul KV +- Secret stores: HashiCorp Vault, Azure KeyVault, AWS Secrets Manager references +- External configuration repositories: document the URI/path of any external config repos (e.g., `spring.cloud.config.server.git.uri`) + +### Step 2: Generate Build Profiles Section + +Identify build-time profiles that affect compilation, packaging, and dependency resolution, and produce the complete `## Build Profiles` section: + +- **Java/Maven**: profiles in `pom.xml` (e.g., `springboot`, `buildDocker`, `dev`, `cloud`) — for each, document activation condition (auto, manual `-P`, system property `-Denv=`), purpose, and key dependencies or plugins added +- **Java/Gradle**: build types and flavors in `build.gradle` +- **.NET**: build configurations (Debug, Release), conditional compilation symbols, MSBuild properties +- **JavaScript/TypeScript**: build scripts in `package.json`, webpack/vite/esbuild configurations per environment + +For each build profile extract: +- Profile name +- Activation condition (automatic, manual flag, system property, environment variable) +- Purpose (what it enables) +- Key dependencies or plugins added/removed + +### Step 3: Generate Runtime Profiles Section + +List all runtime profile-specific or environment-specific configuration and produce the complete `## Runtime Profiles` section: + +- Java (Spring): Profile-specific files (`application-dev.yml`, `application-prod.yml`), `@Profile` annotations, `spring.profiles.active` settings, combined profile activation (e.g., `mysql,key-vault`) +- .NET: Environment-specific files (`appsettings.Development.json`, `appsettings.Production.json`), `ASPNETCORE_ENVIRONMENT` usage +- JavaScript/TypeScript: `.env.development`, `.env.production`, NODE_ENV-based branching +- Identify profile activation conditions, defaults, and how profiles compose (multiple active profiles) + +### Step 4: Generate Properties Inventory Section + +For each service/module, catalog all configuration properties and produce the complete `## Properties Inventory` section: + +- Property keys with their default values +- Which profiles/environments override each property +- Data types and expected value ranges (where inferable) +- Properties sourced from environment variables (`${ENV_VAR}`, `%ENV_VAR%`) +- Placeholder references and property resolution chain + +> Do NOT include JVM startup parameters, `-Xms`/`-Xmx` heap settings, `-D` system properties, container memory/CPU limits, or instance counts here — those belong in the `## Startup Parameters & Resource Requirements` section (Step 5). + +### Step 5: Generate Startup Parameters & Resource Requirements Section + +Document JVM startup options, runtime parameters, and per-service resource allocations, and produce the complete `## Startup Parameters & Resource Requirements` section: + +- JVM heap settings (`-Xms`, `-Xmx`) per service +- System properties passed at startup (`-Dspring.profiles.active=`, `-Dazure.keyvault.uri=`, etc.) +- Docker/container environment variable overrides (`SPRING_PROFILES_ACTIVE`, `ASPNETCORE_ENVIRONMENT`) +- Memory allocation per service (Docker `mem_limit`, Kubernetes `resources.requests/limits`, cloud deployment settings) +- CPU allocation if specified +- Instance count and scaling configuration +- JVM heap settings mapped to service memory allocation (e.g., `-Xms2048m -Xmx2048m` for 2Gi services) + +### Step 6: Generate Startup Dependency Chain Section + +Map the service startup order and readiness dependencies and produce the complete `## Startup Dependency Chain` section: + +- Which services must start before others (e.g., config-server → discovery-server → business services → gateway) +- Health-check/wait mechanisms: `dockerize` wait-for-TCP, Kubernetes readiness probes, Spring Cloud Config retry, Docker Compose `depends_on` with health checks +- Startup timeout configurations +- Service readiness indicators (actuator health endpoints, custom health checks) + +### Step 7: Generate Secrets & Sensitive Configuration Section + +Flag sensitive configuration entries and document the secrets provisioning workflow, and produce the complete `## Secrets & Sensitive Configuration` section (including the `### Secrets Provisioning Workflow` subsection): + +- Database passwords, API keys, connection strings with credentials +- Secret references: KeyVault URIs, Vault paths, encrypted property values +- Entries marked as sensitive by framework conventions (e.g., `spring.datasource.password`) +- **Do NOT output actual secret values** — show the reference path or "[MASKED]" placeholder +- Note encryption methods if present (Jasypt, DPAPI, sealed secrets) + +Document how secrets flow through the system (`### Secrets Provisioning Workflow`): +- Secret source: environment variables, Key Vault, Vault, AWS Secrets Manager, sealed secrets +- Identity/access model: managed identities, service principals, RBAC permissions (e.g., "system-assigned managed identity with `get` and `list` permissions on Key Vault") +- Provisioning sequence: how secrets are set up during deployment (e.g., GitHub Actions retrieves service principal credentials → authenticates → creates MySQL secrets → binds to services) +- Which services need which secrets (e.g., data services need MySQL connection strings, all services need config server credentials) + +### Step 8: Generate Feature Flags Section + +Identify feature toggles and conditional configuration and produce the complete `## Feature Flags` section: + +- Feature flag frameworks: Spring Feature Flags, LaunchDarkly, Unleash, .NET FeatureManagement, custom toggles +- Conditional beans/services (`@ConditionalOnProperty`, `@ConditionalOnExpression`) +- A/B testing flags and gradual rollout configurations +- Default values and controlling sources (config file, environment variable, remote service) + +### Step 9: Generate Framework & Runtime Versions Section + +Catalog the technology stack versions that affect configuration and produce the complete `## Framework & Runtime Versions` section: + +- Core framework versions: Spring Boot, Spring Cloud, ASP.NET Core, Node.js, Express +- Target language/runtime version: Java 8/11/17/21, .NET 6/7/8, Node.js 18/20 +- Key library versions: Hibernate, EF Core, Resilience4j, Eureka, etc. +- Docker base images and their versions (e.g., `openjdk:11-jre`, `mcr.microsoft.com/dotnet/aspnet:8.0`) +- Build tool versions: Maven, Gradle, MSBuild, npm/yarn/pnpm + +### Step 10: Save Output + +Save to `.github/modernize/assessment/engines/facts/configuration-inventory.md` with this exact structure: + +``` +# Configuration & Externalized Settings Inventory + +A brief introduction (1-2 sentences) summarizing the configuration landscape. + +## Configuration Sources + +[Table: Source | Type | Path/Location | Notes] + +## Build Profiles + +[Table: Profile | Activation | Purpose | Key Dependencies/Plugins] + +## Runtime Profiles + +[Table: Profile | Activation Method | Config Files | Key Overrides] + +## Properties Inventory + +[Per-service tables: Property Key | Default | Profiles | Source] + +## Startup Parameters & Resource Requirements + +[Table: Service | JVM/Runtime Options | Memory | Instance Count] + +## Startup Dependency Chain + +[Ordered list: Service → waits for → Service, with mechanism (dockerize, health check, etc.)] + +## Secrets & Sensitive Configuration + +[Table: Secret Reference | Type | Storage (masked)] + +### Secrets Provisioning Workflow + +[Description of how secrets flow: source → identity/access → binding → services] + +## Feature Flags + +[Table: Flag Name | Default | Controlled By] + +## Framework & Runtime Versions + +[Table: Component | Version | Source] +``` + +## Scaling Rules + +- If the project has **more than 100 properties**, group by category (database, messaging, security, etc.) and show representative examples with counts +- For multi-module projects, organize the properties inventory by module/service +- Collapse repetitive property patterns (e.g., 20 similar cache TTL settings) into a summary row with count + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No configuration files found**: Output: `> ERROR: No recognized configuration files found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort inventory from available data. Add a note: `> Note: Some configuration sources or properties could not be fully identified.` + +## Success Criteria + +- Configuration sources table lists all discovered config files, external config repos, and secret stores +- Build profiles are documented separately from runtime profiles with activation conditions and purposes +- Runtime profiles are documented with config files and key overrides +- Properties inventory covers all discovered properties with defaults and sources +- Startup parameters and resource requirements are documented per service +- Startup dependency chain shows service boot order with wait mechanisms +- Secrets are identified with references (no actual values exposed) and the provisioning workflow is described +- Feature flags are cataloged with defaults and controlling sources +- Framework and runtime versions are documented +- File saved to `.github/modernize/assessment/engines/facts/configuration-inventory.md` diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/SKILL.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/SKILL.md index f3b72fe..5b33d17 100644 --- a/plugins/github-copilot-modernization/skills/create-modernization-plan/SKILL.md +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/SKILL.md @@ -9,12 +9,12 @@ This skill is used to create a modernization plan to migrate the a given project ## User Input -modernization-prompt: The user input to generate the modernization plan -modernization-work-folder (Mandatory): The folder to save the modernization plan -github-issue-link (Optional): A github issue to track the modernization status, to be filled into plan template -assessment-report (Optional): A assessment report for the project will be modernized, it will provide the data about the project for modernization -plan-name (Optional): The plan name to be filled into plan template -language (Mandatory): The programming language of the project (java or dotnet) +- modernization-prompt: The user input to generate the modernization plan +- modernization-work-folder (Mandatory): The folder to save the modernization plan +- github-issue-link (Optional): A github issue to track the modernization status, to be filled into plan template +- assessment-report (Optional): A assessment report for the project will be modernized, it will provide the data about the project for modernization +- plan-name (Optional): The plan name to be filled into plan template +- language (Mandatory): The programming language of the project (java or dotnet) ## Supported Task Patterns @@ -36,27 +36,39 @@ Given the user input, do this: 1) Analysis the supported patterns to find the right tasks for the issues 2) Analysis modernization requirement from user input -3. **Generate plan and tasks**: Generate plan.md and tasks.json using the appropriate templates: +3. **Clarification and Questionnaire** (only when the `ask_user` tool is available): If there are any open issues or ambiguities that need user input, use the following steps to answer any questions. Also ask the questions outlined in `questionnaire.md` via `ask_user` tool to scope the modernization plan. For questionnaire questions, if the user input already provides the answer, skip asking that question and use the provided information as the answer. + 1) Use the `ask_user` tool to ask the user each clarification question directly. Wait for the user's response before proceeding. + 2) Record each question and answer for use in the summary step. + 3) If the `ask_user` tool is not available, skip this step entirely and proceed to plan generation using best-effort defaults. + +4. **Generate plan and tasks**: Generate plan.md and tasks.json using the appropriate templates: **Template Selection**: - Use **plan-template.md** for code migration, containerization, and deployment tasks + - Use **security-plan-template.md** to include a security/CVE remediation task in every modernization plan. - Use **infra-plan-template.md** ONLY when user explicitly requests infrastructure (e.g., "prepare infrastructure", "create landing zone", "provision resources", "generate Bicep/Terraform") - **Plan Generation**: + **Plan Generation**: 1) Follow the structure of the selected template to generate the plan 2) Follow the rules defined in the template to fill in the sections with relevant information based on the analysis of user input and content of mentioned files 3) Save the plan in folder ${modernization-work-folder} with the filename plan.md. If a plan already exists, overwrite it. - 4) Generate a separate tasks.json file following the tasks-schema.json schema with all upgrade, transform, infrastructure, containerization, and deployment tasks - 5) Save the tasks in folder ${modernization-work-folder} with the filename tasks.json. If tasks.json already exists, overwrite it. + 4) Generate a separate tasks.json file following the tasks-schema.json schema with setupBaseline, infrastructure, upgrade, transform, containerization, and deployment tasks + 5) Save the tasks in folder ${modernization-work-folder}/.metadata/ with the filename tasks.json. If tasks.json already exists, overwrite it. + **Clarification Outcomes in Plan**: Incorporate all clarification answers from steps 3–4 into `plan.md` and `tasks.json`: + - Update the relevant task's `requirements` or `description` in `tasks.json` based on the answer. Do NOT create a separate task for an implementation detail—only add a new task when the answer introduces entirely new migration scope. + - Record all clarification questions and their outcomes in the **"## Open Questions & Questionnaire"** section of `plan.md`: + - Answered: `- [x] Q: ... → A: ...` + - Unanswered/skipped: `- [ ] ...` + - Remove the section entirely if no clarification questions were raised. **IMPORTANT**: The plan.md should NOT contain the detailed task breakdown. Those details go into tasks.json for better tracking and programmatic access. **Task Breakdown Rules**: When creating tasks for tasks.json and plan.md: - Purpose: Break down coding work into discrete migration tasks. Each task represents a user-requested migration from one service/component to another, or a specific business logic modernization. - - Create tasks ONLY based on what the user explicitly requested - do not infer or add implicit tasks + - Create tasks ONLY based on what the user explicitly requested - do not infer or add implicit tasks, **except** for the security/CVE remediation task which must always be included in every plan + - If an `assessment-report` is provided, the task description must identify which specific issues from the assessment report are addressed by that task (e.g., "Addresses issues: , ") - Group related changes that serve a single user goal into one task (e.g., all changes needed to migrate to PostgreSQL) - - If the JDK version is under 17, add task to upgrade the JDK to latest version unless user specified not to do it - Find a matched skill / pattern for the task, following the following priority order. 1. Skills available for the project, which will be listed in the `skill` tool description. 2. Patterns that will be attached and available at plan execution phase, listed in the supported patterns file. @@ -65,31 +77,43 @@ Given the user input, do this: - You MUST NOT use the pattern name as the skill name in the generated plan and tasks.json. - If there are similar skills defined in project skill `.github/skills/` versus other skills, MUST use the one defined in project. - Skills must be fully matched. For migration scenarios, both the source product and target product must match the task intent. - - Each task should be independently testable with integration tests + - Each task should be independently testable - Do not add tests for unimpacted code or existing functionality unless user requested - **IMPORTANT**: Do NOT read individual skill files at this stage; Do Not include the skill detail in the tasks. - **Java Upgrade Task Guidelines**: Only add upgrade task if the JDK version is under 17 or user explicitly requested. Upgrade task must be the first task if exists. When creating upgrade tasks for Java projects (current latest versions: Java 17+, Spring Boot 3.x+, Spring Framework 6.x+), create the highest-level upgrade task that encompasses all necessary changes: + **Java Upgrade Task Guidelines**: Only add an upgrade task if the user explicitly requests it. You must refer to the ./java-upgrade-guideline.md for specific rules and guidelines when creating Java upgrade tasks. + + **.NET Upgrade Task Guidelines**: You must refer to the ./dotnet-upgrade-guideline.md for specific rules and guidelines when creating .NET upgrade tasks. + + **Deployment Task Rules**: + - **IMPORTANT** Do NOT create task type with `containerization` if deployment task already exists, deployment task will cover the containerization work if needed. + - Deployment Task Options: Azure App Service, Azure Kubernetes Service, Azure Container Apps (default), Azure App Service Managed Instance, Azure Static Web App, Azure Function App - - **Spring Boot 3.x upgrade** (when Java 21+ not explicitly requested): - - Create a single task: "Upgrade Spring Boot to 3.x" - - Include in task description: This upgrade includes JDK 17, Spring Framework 6.x, and migration from JavaEE (javax.*) to Jakarta EE (jakarta.*) + **Security Task Guidelines**: The security task order should be after all the upgrade and transform tasks and before the deployment tasks in the generated plan. If the user provides specific security requirements, incorporate them into the security task; otherwise, use the default requirements from the template. - - **Spring Framework 6.x upgrade** (when Java 21+ not explicitly requested and Spring Boot not being upgraded): - - Create a single task: "Upgrade Spring Framework to 6.x" - - Include in task description: This upgrade includes JDK 17 + **IMPORTANT**: The upgrade task must be the first task in the task list because subsequent transform tasks (e.g., migrating to Azure services) depend on the upgraded runtime and project format. - - **Java 21+ upgrade** (when explicitly requested): - - Create a single task: "Upgrade Java to version X" - - Include in task description: Specify the target version and related framework impacts +5. **Rulebook Compliance Validation** (only when rulebook attachments are present): + After generating the plan and tasks, call skill `validate-rulebook-compliance` to validate that the plan tasks cover the rulebook rules: + - tasks-json-path: `${modernization-work-folder}/.metadata/tasks.json` + - compliance-output-path: `${modernization-work-folder}/rulebook-compliance.md` + - This validation is **best-effort only** and must **not** block or fail plan creation. + - If the validation call cannot run, fails, or required context/attachments are missing, you must still complete the workflow and emit `${modernization-work-folder}/plan.md` and `${modernization-work-folder}/.metadata/tasks.json`. + - If validation cannot be completed successfully, write a minimal warning/status report to `${modernization-work-folder}/rulebook-compliance.md` explaining that validation was skipped or failed and why, if known. -4. **Clarification**: If there are any open issues in the plan - 1) Return all the open issues to user for clarification - 2) After user clarified, update the plan +6. **Summary & Confirmation** (only when the `ask_user` tool is available): + 1) Present a summary to the user via `ask_user` that includes: + - All clarification questions and the user's answers (if any were asked in step 3) + - The planned task list with key details for each task: task name, type, matched skill/pattern, and a brief description of what it will do + - The supported task type in task-schema.json but not listed in the planned task list but matched with the user requirement, ask the user if they want to include those tasks in the plan or not. + 2) Ask the user to confirm the summary is correct, or provide additional input to adjust any answers or task list. + 3) If the user provides additional input, incorporate the changes. If the user chooses to skip or confirms, proceed to plan generation. + 4) If the `ask_user` tool is not available, skip this step entirely. ## Completion Criteria -1. All the open issues are clarified and the plan is updated +1. All clarification & questionnaire questions have been asked (or skipped with defaults) via `ask_user`, answers incorporated into `plan.md` and `tasks.json`, and outcomes recorded in the "## Open Questions & Questionnaire" section of `plan.md` 2. The modernization task list is built 3. The modernization task list MUST be scoped according to user input 4. DON'T RUN the plan if user does not explicitly ask you to run the plan +5. The generated plan.md and tasks.json are saved in the specified folder `${modernization-work-folder}` diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/dotnet-upgrade-guideline.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/dotnet-upgrade-guideline.md new file mode 100644 index 0000000..a5c97e0 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/dotnet-upgrade-guideline.md @@ -0,0 +1,43 @@ +# .NET Upgrade Task Guidelines + +Only add a .NET upgrade task if one of the following conditions is met: + +1. **End of Life (EOL)**: The project's .NET version is out of mainstream support. +2. **Azure SDK Compatibility**: The project targets a .NET Framework version older than 4.6.2, which does not support `netstandard2.0` and cannot use modern Azure SDK (`Azure.*`) packages. +3. **User Request**: The user explicitly requests a .NET version upgrade. + +The upgrade task must be the first task if it exists. + +### Target Version + +Always upgrade to the **latest LTS** version unless the user explicitly specifies a different target version. + +- Current latest LTS: **.NET 10** (`net10.0`) + +### Azure SDK Minimum .NET Version + +The modern Azure SDK for .NET (`Azure.*` packages) targets `netstandard2.0` as its baseline. The following .NET Framework versions do **not** support `netstandard2.0` and require an upgrade: + +| .NET Framework Version | `netstandard2.0` Support | Action | +|------------------------|:------------------------:|--------| +| 4.5 and below | ❌ | Upgrade required | +| 4.6 | ❌ | Upgrade required | +| 4.6.1 | ⚠️ Unreliable | Upgrade recommended | +| 4.6.2+ | ✅ | No upgrade needed for Azure SDK compatibility | + +> **Note**: .NET Framework 4.6.1 is technically listed as supporting `netstandard2.0` but has known issues. Microsoft recommends 4.7.2+ for reliable support. The Azure SDK explicitly targets `net462` as its minimum. + +## Framework Compatibility + +| Source Framework | Target Framework | SDK-Style Conversion Required | +|-----------------|:----------------:|:----------------------------:| +| .NET Framework 4.x | net10.0 | Yes | +| .NET Core 3.1 | net10.0 | No | +| .NET 5–9 | net10.0 | No | + +## .NET Task Selection Rules + +- **Rule 1 — Single task only**: Always create a **single** upgrade task that encompasses all necessary changes. The `modernize-dotnet-upgrade-engineer` agent handles the detailed breakdown during execution. +- **Rule 2 — EOL or Azure SDK incompatibility**: Create task "Upgrade .NET to latest LTS (net10.0)". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 3 — User-specified version**: Create task "Upgrade .NET to version X". Set the task `skills` array to `[]` (empty) — the upgrade agent handles execution internally. +- **Rule 4 — No upgrade needed**: If the project's .NET version is in support **and** the project targets .NET Framework 4.6.2+ (or any .NET Core / modern .NET) **and** the user did not request an upgrade, do **not** add an upgrade task. \ No newline at end of file diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/infra-plan-template.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/infra-plan-template.md index ea5bc30..d61d6bd 100644 --- a/plugins/github-copilot-modernization/skills/create-modernization-plan/infra-plan-template.md +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/infra-plan-template.md @@ -27,11 +27,13 @@ Use this template when user explicitly requests infrastructure preparation (e.g. --- ## Azure Resource List -A complete list of Azure resources to be generated. +A complete list of Azure resources to be generated. Use `#appmod-get-azure-pricing` to retrieve pricing information for each resource. -| Resource Type | Resource Name | SKU | Purpose | -|---------------|---------------|-----|---------| -| [e.g., SQL Database] | [e.g., sqldb-myapp-prod] | [e.g., S1] | [Purpose] | +| Resource Type | Resource Name | SKU | Est. Monthly Cost | Purpose | +|---------------|---------------|-----|--------------------|---------| +| [e.g., SQL Database] | [e.g., sqldb-myapp-prod] | [e.g., S1] | [e.g., $25/mo] | [Purpose] | + +> **Note**: The estimated costs shown above are based on Azure retail prices and serve only as a rough estimation. Actual costs may differ due to enterprise agreements, reservations, or other discounts. For consumption-based (pay-as-you-go) resources, costs depend on actual usage and cannot be accurately estimated upfront. --- @@ -39,16 +41,10 @@ A complete list of Azure resources to be generated. **Description**: Generate IaC files to provision the required Azure resources. -**Output**: ./infra/ +**Output**: Files of infrastructure as code **Skill**: [infrastructure-bicep-generation | infrastructure-terraform-generation] **Success Criteria**: - IaC files generated and validated - Resources provisioned successfully (if Provision=true) - ---- - -## Clarifications - -[Optional: Only list the most critical items that MUST be confirmed before provisioning. Keep it minimal.] diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/java-upgrade-guideline.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/java-upgrade-guideline.md new file mode 100644 index 0000000..270412a --- /dev/null +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/java-upgrade-guideline.md @@ -0,0 +1,44 @@ +# Java Upgrade Task Guidelines + +Only add an upgrade task if the user explicitly requests it. The upgrade task must be the first task if it exists. + +## Latest Stable Versions + +- Java: 25 +- Spring Boot: 4.x +- Spring Framework: 7.x + +## Supported Upgrade Versions + +- Java: 11, 17, 21, 25 +- Spring Boot: 3.x, 4.x +- Spring Framework: 6.x, 7.x + +## Framework Compatibility + +| Spring Boot | Spring Framework | Jakarta EE | Minimum Java | Maximum Java | +|-------------|:----------------:|:----------:|:------------:|:------------:| +| 2.x | 5.x | JavaEE (javax.*) | 8 | 11 | +| 3.x | 6.x | Jakarta EE (jakarta.*) | 17 | 21 | +| 4.x | 7.x | Jakarta EE (jakarta.*) | 25 | 25 | + +## Upgrade Task Types and Included Changes + +| Task Type | Spring Framework Upgrade | Jakarta EE Migration (javax.* → jakarta.*) | JDK/Java | +|-----------|:------------------------:|:------------------------------------------:|:-----------:| +| Spring Boot 4.x upgrade | 7.x | ✓ | 25 | +| Spring Boot 3.x upgrade | 6.x | ✓ | 21 | +| Spring Framework 7.x upgrade | — | ✓ | 25 | +| Spring Framework 6.x upgrade | — | ✓ | 21 | +| Jakarta EE upgrade | — | ✓ | 21 | +| JDK/Java upgrade | — | — | to specified version | + +## Java Task Selection Rules + +When selecting the Java upgrade task type, follow these rules in order: + +- **Rule 1 — No redundant sub-tasks**: Each upgrade type (Spring Boot, Spring Framework, Jakarta EE, JDK/Java) is hierarchical — higher-level tasks already include lower-level ones. Never create a lower-level task that is already covered by a selected higher-level task. For example, if a Spring Boot 4.x upgrade task is selected (which already includes JDK 25), do NOT also create a separate JDK/Java upgrade task. +- **Rule 2 — User-specified framework request doesn't fully match system state**: When the user requests a **framework** upgrade (e.g., Spring Boot, Spring Framework) but the target version they specify is not the latest available, select the highest-level task applicable and prompt the user to clarify. For example, if the user asks to "upgrade Spring Boot to 3.x" but Spring Boot 4.x is available, create a Spring Boot 3.x upgrade task and add a clarification question asking whether they want 4.x. **This rule does NOT apply to pure JDK/Java upgrade requests — see Rule 4.** +- **Rule 3 — User-specified request matches system state**: Select the most closely matching task type that directly matches the user's request and fits the system. For example, if the user asks to "upgrade JDK" and the JDK is outdated, create a JDK/Java upgrade task — NOT a higher-level Spring Boot or Spring Framework upgrade task. +- **Rule 4 — Never upgrade other frameworks on a JDK/Java request**: When the user explicitly requests a JDK/Java upgrade, you MUST NOT upgrade Spring Boot, Spring Framework, or Jakarta EE — create only a JDK/Java upgrade task targeting the user-specified version. If the project's existing Spring Boot, Spring Framework, or Jakarta EE versions are incompatible with the target Java version (per the Framework Compatibility table above), add a clarification question asking the user whether they also want to upgrade the incompatible framework(s) to a compatible version. +- **Rule 5 — Ask for clarification when the selected task diverges from the user's request**: Whenever the task you create differs from what the user explicitly asked for (e.g., upgrading to a different version, choosing a higher-level task type, or skipping a requested change due to compatibility), you MUST use the `ask_user` tool to explain what was selected, why it differs, and ask the user to confirm or adjust. If `ask_user` is not available, add the question to the "## Open Questions" section of `plan.md`. Never silently override the user's intent. \ No newline at end of file diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/plan-template.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/plan-template.md index 017b925..9075212 100644 --- a/plugins/github-copilot-modernization/skills/create-modernization-plan/plan-template.md +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/plan-template.md @@ -58,19 +58,13 @@ Use this template to generate modernization plans for applications. Replace plac --- -## Clarifications +## Open Questions & Questionnaire -**Purpose**: Document items that were not explicitly requested by the user but may be necessary or beneficial. Ask the user to confirm or provide input. - -**Rule**: Only include this section if there are implicit dependencies, nice-to-have features, or ambiguities in the user's request. +**Purpose**: Record all clarification questions raised during plan creation and their resolution status. Record all answers to questionnaire questions. **Template**: ```markdown -The following items were not explicitly requested but may be needed for a complete implementation: - -1. **[Item Name]**: [Description of what needs clarification] - - **Why needed**: [Explain the dependency or benefit] - - **Options**: [List possible approaches or choices] - - **Recommendation**: [Suggest a default if user doesn't respond] - +- [x] Q: What authentication method should be used for Azure Storage? → A: Use managed identity +- [ ] Which region should the deployment target? ``` + diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/questionnaire.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/questionnaire.md new file mode 100644 index 0000000..8a87b16 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/questionnaire.md @@ -0,0 +1,40 @@ +# Clarification Questionnaire + +Infer answers from available context (assessment report, user prompt, project structure) before asking the user. Only present a question via `ask_user` when the answer cannot be determined. When asking, show all options and mark the default. Record every answer (inferred or user-provided) for inclusion in the plan's "Open Questions & Questionnaire" section. + +## Environment Setup + +Should the plan include environment/infrastructure provisioning? + +* (Default if no infra configuration found) No — no infrastructure provisioning; focus on code migration only +* (Default if infra configuration found) No — use infrastructure/configuration already defined in the repository (for example, existing IaC, deployment manifests, or pipeline config) +* Yes — provision new infrastructure +* Custom — use an existing externally managed environment specified by the user instead of provisioning or repo-defined configuration (ask for resource group, subscription, environment name, or config path) + +## Security & CVE Remediation + +Should the plan include a security scan and CVE remediation task? This task runs after all upgrade and transform tasks and before deployment to identify and fix known vulnerabilities. + +* (Default) Yes — include security/CVE remediation +* No — skip security/CVE remediation +* Custom - user input the security/CVE requirements + +## Deployment Target + +Which Azure deployment target should the plan use? + +* (Default) Azure Container Apps — includes containerization; no separate containerization task needed +* Azure Kubernetes Service — includes containerization; no separate containerization task needed +* Azure App Service +* Azure App Service Managed Instance +* Azure Function App +* Azure Static Web App +* No deployment — migration only, no cloud deployment +* Custom — user-specified target (ask for details) + +## Containerization + +Should the plan include containerization (Dockerfile generation)? Skip this question if the deployment target already includes containerization (Azure Container Apps or AKS). + +* (Default) Yes — generate Dockerfile and container build configuration +* No — skip containerization diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/security-plan-template.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/security-plan-template.md new file mode 100644 index 0000000..3a641b7 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/security-plan-template.md @@ -0,0 +1,26 @@ +## Security Compliance + +**Purpose**: Scan and remediate CVEs (Common Vulnerabilities and Exposures) in project dependencies to ensure the modernized application is free of known security vulnerabilities. + +**Condition**: Always include this task in every modernization plan. Do not include this task if the user explicitly requests that it be removed. + +**Template**: + +**Description**: Scan all project dependencies for known CVEs and remediate any identified vulnerabilities to ensure the application is secure before deployment. + +**Requirements**: + Upgrade vulnerable dependencies to the minimum patched version. If a CVE fix requires a major version upgrade, document the affected dependency, the current version, the upgraded major version, and the breaking change risk. Verify that the project builds and all tests pass after remediation. + If the user provided specific security requirements, incorporate them as well. + +**Environment Configuration**: + Runtime environment established by previous tasks (e.g., Java Home, .NET runtime). + Build tool established by previous tasks (e.g., Maven/Gradle, dotnet). + +**App Scope**: + The app folders that this task will operate on + +**Skills**: + - Skill Name: validate-cves-and-fix + - Skill Location: builtin + - Skill Name: [additional skill if needed] + - Skill Location: [Skill location] \ No newline at end of file diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-dotnet.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-dotnet.md new file mode 100644 index 0000000..2015033 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-dotnet.md @@ -0,0 +1,52 @@ +## Supported Task Patterns + +The following are the task patterns supported by the modernize CLI. These patterns are used to identify the modernization tasks that need to be performed based on the user's input. + +The patterns are categorized into two groups, and they should be treated differently if picked: + +* Patterns with skill definitions: These patterns have pre-defined skills that can be used to execute the tasks. If a task matches one of these patterns, the corresponding skill should be used in the task plan. +* Patterns without skill definitions: These patterns do not have pre-defined skills. If a task matches one of these patterns, the description should be used to guide the AI in performing the required tasks. + **IMPORTANT**: The pattern name should NEVER be used as the skill name in the generated plan and tasks.json. They are meant to guide the task generation, not to be directly used as skills. + + +### Task Patterns with Skill Definitions +These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. +Each of the item is written in the following format: `- **skill-name**: skill-description`. + +- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli +- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow +- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow +- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli +- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow +- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. +- **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning +- **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning +- **migration-azure-communication-email**: This knowledge base provides knowledge about how to use Azure Communication Services for sending emails in .NET applications, covering authentication with Managed Identity, configuration, and email operations. +- **migration-azure-confluent-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Confluent Cloud on Azure, using Azure Managed Identity and DefaultAzureCredential. +- **migration-azure-database-postgresql**: This file provides guidance for migrating .NET applications to Azure Database for PostgreSQL with passwordless Managed Identity, covering both Entity Framework Core and non-EF Core applications. +- **migration-azure-eventhubs-kafka**: This knowledge base provides knowledge about migrating .NET applications using Confluent.Kafka from local Kafka to Azure Event Hubs for Kafka, using Azure Managed Identity and DefaultAzureCredential. +- **migration-azure-keyvault-certificate**: This file provides guidance on using Azure Key Vault certificate management in .NET, covering authentication, configuration, and certificate operations. +- **migration-azure-keyvault-secret**: This file provides guidance on using Azure Key Vault secrets in .NET, covering authentication, configuration, and secret operations. +- **migration-azure-redis-cache**: This knowledge base provides guidance for adding distributed caching with Azure Cache for Redis to .NET applications, or migrating existing caching implementations (in-memory cache, Redis, or other providers) to use Azure Cache for Redis with DefaultAzureCredential (Managed Identity) authentication. +- **migration-azure-servicebus**: This knowledge base provides knowledge about migrating .NET applications to use Azure Service Bus with Managed Identity, covering queue and topic operations, message handling, and processor configurations. +- **migration-azure-sql-database**: This knowledge base provides knowledge about migrating .NET applications to use Azure SQL Database and Azure SQL Managed Instance with Managed Identity authentication, including Entity Framework 6 provider configuration. +- **migration-azure-storage-blob**: This knowledge base provides comprehensive knowledge about using Azure Storage Blob SDK in .NET applications, covering Managed Identity authentication, blob operations, container management, and SAS token generation. +- **migration-azure-storage-mount**: This knowledge base provides knowledge about migrating .NET applications from using hard-coded local file paths to Azure mounted storage paths while maintaining the same functionality. +- **migration-console-logging**: This knowledge base provides knowledge about configuring console logging in .NET applications for cloud environments, ensuring proper log output for container and cloud platform log aggregation. +- **migration-dependency-management**: Comprehensive guide for understanding and implementing dependency management in .NET projects, covering both modern SDK-style projects (.NET Core, .NET 5+) and legacy .NET Framework projects. Includes package reference management, project file structure, and migration considerations. +- **migration-local-appsettings-azure-app-configuration**: This knowledge base provides guidance on moving non-secret application settings from appsettings.json / appsettings.{Environment}.json into Azure App Configuration while preserving the existing IConfiguration / IOptions shape, and emitting a `.azure/configuration-migration.json` seed file for the deployment agent. +- **migration-local-appsettings-azure-app-configuration-via-deployment**: This knowledge base provides guidance on externalizing non-secret values from appsettings.json to Azure App Configuration without adding the App Configuration SDK. The only allowed application-side change is ensuring the environment-variable configuration source is registered so that values injected by the deployment agent are visible through IConfiguration. The migration agent writes the `.azure/configuration-migration.json` contract; the deployment agent injects the values at runtime as App Service application settings or as a Kubernetes ConfigMap/Secret produced by the Azure App Configuration Kubernetes Provider. +- **migration-managed-identity**: Comprehensive guidance for migrating .NET applications to use Azure Managed Identity for authentication instead of connection strings, client secrets, certificates, or other credential-based authentication methods. Covers Azure SQL, Storage, Key Vault, Service Bus, Event Hubs, Cosmos DB, and more. +- **migration-microsoft-entra-id**: This knowledge base provides knowledge about migrating .NET applications to use Microsoft Entra ID (formerly Azure AD) for authentication, including ASP.NET Core, ASP.NET Web Forms, and Microsoft Graph integration. +- **migration-opentelemetry-azure**: This guide describes how to implement OpenTelemetry in .NET with Azure Monitor for tracing, metrics, and logging migration. + +### Task Patterns without Skill Definitions +These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. + +A pattern should be selected if it matches one of the customer's requirements, and there are no skills supporting this requirement. + +**IMPORTANT**: +- NEVER write the pattern name as skill name in the generated plan. +- Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. + + diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-java.md b/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-java.md index fa23177..6ae2dee 100644 --- a/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-java.md +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/supported-patterns-java.md @@ -13,25 +13,47 @@ The patterns are categorized into two groups, and they should be treated differe These patterns have pre-defined skills to assist in their execution. When they are selected in a modernization plan, the corresponding skills should be used. Each of the item is written in the following format: `- **skill-name**: skill-description`. +- **azcli-aks-deploy**: Generate plan for deploying to existing Azure Resources for Azure Kubernetes Service, using azcli +- **azcli-appservice-deploy**: Deployment steps for Azure App Service under the AzCLI flow +- **azcli-appservicemi-deploy**: Deployment steps for Azure App Service Managed Identity under the AzCLI flow +- **azcli-containerapp-deploy**: Generate plan for deploying to existing Azure Resources for Azure Container Apps, using azcli +- **azcli-functionapp-deploy**: Deployment steps for Azure Function App under the AzCLI flow +- **containerization**: Setup Dockerfiles for the project to run inside of containers for Azure Container Apps or Azure Kubernetes Service. - **infrastructure-bicep-generation**: Generate Bicep IaC files for Azure infrastructure provisioning - **infrastructure-terraform-generation**: Generate Terraform IaC files for Azure infrastructure provisioning -- **migration-cache-related-code-to-redis**: Provides knowledge for migrating cache related code to use Redis, and potentially to Azure Managed Redis / Azure Cache for Redis (retiring) while following best practices. Use this skill when users want to migrate their cache related code to use Redis, such as Apache Commons JCS, DynaCache, Embedded cache, JCache, OSCache, ShiftOne, Oracle Coherence, etc., or local Redis to Azure Managed Redis / Azure Cache for Redis (retiring) with secure authentication changes. -- **migration-activemq-servicebus**: Migrate from ActiveMQ Artemis to Azure Service Bus for messaging. -- **migration-amqp-rabbitmq-servicebus**: Migrate from RabbitMQ with AMQP to Azure Service Bus for messaging. -- **migration-ant-project-to-maven-project**: Migrate current project from Ant project to Maven project -- **migration-deprecated-api-upgrade**: Upgrade deprecated APIs to their recommended alternatives for improved security, performance, and compatibility. -- **migration-eclipse-project-to-maven-project**: Migrate current project from eclipse project to maven project -- **migration-java-ee-amqp-rabbitmq-servicebus**: Migrate from RabbitMQ with AMQP to Azure Service Bus for messaging in Java EE/Jakarta EE applications. -- **migration-jax-rpc-to-jax-ws**: Migrate from JAX-RPC to JAX-WS for web services. JAX-RPC is deprecated and JAX-WS is the recommended alternative. -- **migration-kafka-to-eventhubs**: Migrate from Kafka to Azure Event Hubs for Apache Kafka with managed identity for secure, credential-free authentication. -- **migration-mi-azure-sql**: Secure Azure SQL with managed identity. -- **migration-mi-mariadb**: Migrate from MariaDB to Azure Database for MariaDB with managed identity for secure, credential-free authentication. -- **migration-mi-mongodb**: Secure Azure DocumentDB (with MongoDB Compatibility) with Microsoft Entra ID authentication for credential-free access. -- **migration-mi-mysql**: Migrate from MySQL to Azure Database for MySQL with managed identity for secure, credential-free authentication. -- **migration-mi-postgresql**: Migrate from PostgreSQL to Azure Database for PostgreSQL with managed identity for secure, credential-free authentication. -- **migration-on-premises-user-authentication-to-microsoft-entra-id**: Migrate the user authentication to Microsoft Entra ID authentication -- **migration-oracle-to-postgresql**: Migrate from Oracle DB to PostgreSQL -- **migration-spring-jms-rabbitmq-servicebus**: Migrate from RabbitMQ with JMS to Azure Service Bus for a managed messaging service with JMS API support. +- **migration-AWS-secrets-manager-to-azure-key-vault**: Migrates Java applications from AWS Secrets Manager (SecretsManagerClient, AWSSecretsManager) to Azure Key Vault SecretClient for secrets management. Use when migrating Java projects from AWS to Azure, replacing AWS secret storage with Azure Key Vault, or modernizing cloud secret management. +- **migration-activemq-servicebus**: Migrates Java Spring Boot applications from ActiveMQ JMS messaging to Azure Service Bus JMS. Replaces ActiveMQ dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from ActiveMQ to Azure Service Bus or modernizing on-premises messaging to Azure. +- **migration-amqp-rabbitmq-servicebus**: Migrates Java Spring applications from RabbitMQ AMQP messaging to Azure Service Bus via Spring Messaging. Replaces Spring AMQP RabbitMQ dependencies, updates connection settings, and migrates message producers and consumers. Use when migrating Spring applications from RabbitMQ to Azure Service Bus or replacing on-premises message brokers with Azure managed messaging. +- **migration-ant-project-to-maven-project**: Migrates Java projects from Ant build system to Maven, converting build.xml to pom.xml and restructuring directories to Maven standard layout. Use when modernizing Java projects that use Ant builds, converting to Maven for dependency management, or standardizing build tooling. +- **migration-auth-by-mi-for-azure-redis-in-micronaut-project**: Secure Azure Cache for Redis with Managed Identity via Micronaut +- **migration-certificate-management-to-azure-key-vault**: Migrates Java TLS/MTLS certificate management from local KeyStore storage to Azure Key Vault JCA (Java Cryptography Architecture). Replaces local certificate handling with Azure Key Vault for centralized certificate management. Use when migrating Java applications that use local KeyStore, SSLContext, or Certificate classes to Azure Key Vault for secure certificate storage. +- **migration-confluent-cloud-kafka**: Migrates Java applications from self-hosted Apache Kafka to Apache Kafka on Confluent Cloud with passwordless authentication via Microsoft Entra ID. Updates Kafka connection configuration and authentication settings. Use when migrating Java Kafka producers or consumers to Confluent Cloud or enabling passwordless Entra ID authentication for Kafka on Confluent Cloud. +- **migration-cryptography-operations-to-azure-key-vault**: Migrates Java cryptographic operations (Cipher, Signature) from local key management to Azure Key Vault for centralized key management and cryptographic operations. Use when migrating Java applications that use javax.crypto.Cipher or java.security.Signature to Azure Key Vault, or centralizing cryptographic key management in Azure. +- **migration-eclipse-project-to-maven-project**: Migrates Java projects from Eclipse IDE project format (.project, .classpath) to Apache Maven project structure with pom.xml. Converts Eclipse build configuration and classpath settings to Maven conventions. Use when modernizing Eclipse-based Java projects to Maven, converting .project/.classpath files, or standardizing build tooling. +- **migration-ibm-db2-to-azure-postgresql**: Migrate IBM Db2 to Azure Database for PostgreSQL +- **migration-ibm-db2-to-azure-sql**: Migrate IBM Db2 to Azure SQL Database +- **migration-informix-to-postgresql**: Migrates Java application database layer from Informix Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Informix-specific feature replacement. Use when migrating Java applications from Informix to PostgreSQL, converting Informix SQL to PostgreSQL syntax, or replacing Informix JDBC drivers. +- **migration-java-ee-amqp-rabbitmq-servicebus**: Migrates Java EE/Jakarta EE applications from RabbitMQ AMQP messaging to Azure Service Bus SDK. Replaces RabbitMQ client dependencies, migrates publishers and consumers, updates connection management, and maps RabbitMQ concepts (exchanges, queues) to Service Bus equivalents (topics, subscriptions). Use when migrating Java EE or Jakarta EE applications from RabbitMQ to Azure Service Bus. +- **migration-javax.email-send-to-azure-communication-service-email**: Migrates Java applications from JavaMail (javax.mail) API to Azure Communication Service Email for sending emails. Replaces JavaMail email sending, message construction, and authentication with Azure Communication Service equivalents. Use when migrating Java applications from JavaMail or SMTP-based email sending to Azure Communication Service Email. +- **migration-jax-rpc-to-jax-ws**: Migrates Java web service implementations from deprecated JAX-RPC to JAX-WS. Updates web service configuration files and JAX-RPC specific code to use JAX-WS equivalents. Use when modernizing Java web services that use JAX-RPC or upgrading deprecated JAX-RPC APIs to the JAX-WS standard. +- **migration-kafka-to-eventhubs**: Migrates Java applications from Kafka to Azure Event Hubs for Kafka with managed identity for secure, passwordless authentication. Updates Spring Cloud Azure dependencies, Kafka connection settings, and authentication configuration. Use when migrating Java Kafka producers or consumers to Azure Event Hubs, or enabling managed identity authentication for event streaming. +- **migration-log-to-console**: Migrates Java application logging from file-based output to console-only output. Removes file appenders from logging configuration (logback, logging.xml) and ensures all log output goes to console. Use when containerizing Java applications, migrating to cloud-native logging, or preparing Java apps for Azure where console logging is preferred. +- **migration-mi-azure-sql**: Migrates Java Spring Boot projects from password-based authentication to Azure Managed Identity for connecting to Azure SQL Database. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure SQL Database connections, removing hardcoded database passwords, or securing Java Spring Boot database authentication. +- **migration-mi-cassandra**: Migrates Java applications to connect to Azure Cosmos DB for Apache Cassandra using managed identity via Service Connector in Azure public cloud. Updates CqlSession configuration and Spring Data Cassandra properties. Use when migrating Java or Spring Boot applications to Azure Cosmos DB Cassandra API, enabling managed identity for Cassandra connections, or replacing Cassandra password authentication. +- **migration-mi-eventhub**: Migrates Java projects from password-based authentication to Azure Managed Identity for connecting to Azure Event Hubs. Adds Spring Cloud Azure dependencies and updates Event Hubs and Kafka configuration for passwordless authentication. Use when enabling managed identity for Azure Event Hubs in Java applications, removing Event Hubs connection string passwords, or securing event streaming authentication. +- **migration-mi-mariadb**: Migrates Java applications from password-based MariaDB authentication to Azure Managed Identity for Azure Database for MariaDB in public cloud using AzureMysqlAuthenticationPlugin. Updates JDBC connection and authentication configuration. Use when enabling managed identity for Azure Database for MariaDB, removing MariaDB passwords, or implementing credential-free MariaDB authentication in Azure. +- **migration-mi-mongodb**: Migrate from password-based authentication to Microsoft Entra ID authentication for Azure DocumentDB (with MongoDB Compatibility) in Java projects +- **migration-mi-mysql**: Migrates Java Spring Boot projects from password-based MySQL authentication to Azure Managed Identity for Azure Database for MySQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure MySQL connections in Spring Boot, removing hardcoded MySQL passwords, or securing Spring datasource authentication. +- **migration-mi-postgresql**: Migrates Java Spring Boot projects from password-based PostgreSQL authentication to Azure Managed Identity for Azure Database for PostgreSQL. Updates Spring Cloud Azure dependencies and datasource configuration for passwordless authentication. Use when enabling managed identity for Azure PostgreSQL connections in Spring Boot, removing hardcoded PostgreSQL passwords, or securing Spring datasource authentication. +- **migration-mi-servicebus**: Azure Service Bus Managed Identity via Spring +- **migration-on-premises-user-authentication-to-microsoft-entra-id**: Migrates Java Spring Boot application user authentication from on-premises login to Microsoft Entra ID using spring-cloud-azure-starter-active-directory and spring-boot-starter-oauth2-client. Use when migrating Java web application authentication to Microsoft Entra ID, modernizing on-premises login to cloud identity, or adding Azure Active Directory authentication. +- **migration-oracle-to-postgresql**: Migrates Java application database layer from Oracle Database to PostgreSQL, including JDBC driver changes, SQL syntax conversion, and Oracle-specific feature replacement. Uses project-specific coding_notes.md guidance when available. Use when migrating Java applications from Oracle to PostgreSQL, converting Oracle SQL to PostgreSQL syntax, or replacing Oracle JDBC drivers. +- **migration-other-cache-solutions-to-azure-managed-cache**: Migrate other cache solutions to use Redis, and potentially to Azure Managed Redis / Azure Cache for Redis (retiring) while following best practices. Use this skill when users want to migrate other cache solutions to use Redis, such as Apache Commons JCS, DynaCache, Embedded cache, JCache, OSCache, ShiftOne, Oracle Coherence, etc., or local Redis to Azure Managed Redis / Azure Cache for Redis (retiring) with secure authentication changes. +- **migration-plaintext-credential-to-azure-keyvault**: Migrates hardcoded plaintext credentials (passwords, secrets, API keys, connection strings, tokens) in Java source code to Azure Key Vault for secure storage and retrieval. Use when securing Java applications by removing hardcoded credentials, migrating plaintext secrets to Azure Key Vault, or implementing centralized secret management. +- **migration-s3-to-azure-blob-storage**: Migrates Java applications from Amazon S3 SDK to Azure Blob Storage SDK, including bucket/container operations, object storage, access policies, and SAS token generation. Use when migrating Java applications from AWS S3 to Azure Blob Storage, replacing S3Client with BlobServiceClient, or converting AWS storage APIs to Azure equivalents. +- **migration-spring-jms-rabbitmq-servicebus**: Migrates Java Spring Boot applications from RabbitMQ JMS messaging to Azure Service Bus JMS. Replaces RabbitMQ JMS dependencies with Spring Cloud Azure Service Bus JMS starter and updates connection configuration. Use when migrating Spring JMS applications from RabbitMQ to Azure Service Bus, replacing RMQConnectionFactory, or modernizing JMS messaging to Azure. +- **migration-sqs-to-servicebus**: Migrates Java applications from AWS Simple Queue Service (SQS) to Azure Service Bus for message queuing. Replaces AWS SQS SDK dependencies with Azure Service Bus SDK, updates message sending and receiving code, and migrates queue configuration. Use when migrating Java applications from AWS SQS to Azure Service Bus, replacing SQS client code, or modernizing cloud message queuing to Azure. +- **migration-sybase-ase-to-azure-sql-database**: Migrates Java application database layer from Sybase ASE (Adaptive Server Enterprise) to Azure SQL Database with passwordless managed identity authentication. Use when migrating Java applications from Sybase ASE to Azure SQL. ### Task Patterns without Skill Definitions These patterns DO NOT have pre-defined skills. The pattern name and description define the modernization scenario, NOT A SKILL. They are in the format of `- **pattern-name**: pattern-description`. @@ -41,3 +63,26 @@ A pattern should be selected if it matches one of the customer's requirements, a **IMPORTANT**: - NEVER write the pattern name as skill name in the generated plan. - Tasks generated from these patterns must have NO skill assigned. Do not reuse any skill from the "Task Patterns with Skill Definitions" section, even if a skill targets a similar technology or appears related. + +- **amazon-kinesis-to-azure-event-hubs**: Amazon Kinesis to Azure Event Hubs +- **amazon-sns-to-azure-service-bus**: Amazon SNS to Azure Service Bus +- **apache-pulsar-to-azure-event-hubs**: Apache Pulsar to Azure Event Hubs +- **aws-lambda-to-azure-functions**: AWS Lambda to Azure Functions +- **firebird-to-azure-postgresql**: Firebird to Azure PostgreSQL +- **google-cloud-bigtable-to-azure-cosmos-db**: Google Cloud Bigtable to Azure Cosmos DB +- **google-cloud-functions-to-azure-functions**: Google Cloud Functions to Azure Functions +- **google-cloud-pub-sub-to-azure-service-bus**: Google Cloud Pub/Sub to Azure Service Bus +- **google-cloud-spanner-to-azure-postgresql**: Google Cloud Spanner to Azure PostgreSQL +- **google-cloud-storage-to-azure-blob-storage**: Google Cloud Storage to Azure Blob Storage +- **google-firestore-to-azure-cosmos-db**: Google Firestore to Azure Cosmos DB +- **ibm-db2-to-azure-postgresql**: IBM DB2 to Azure PostgreSQL +- **ibm-mq-jms-to-azure-service-bus**: IBM MQ JMS to Azure Service Bus +- **migration-local-certificate-management-to-azure-key-vault**: Local certificate management to Azure Key Vault +- **migration-local-files-to-mounted-azure-storage**: Local files to mounted Azure Storage paths (starts with `${AZURE_MOUNT_PATH:/mnt/azure}`) +- **quartz-scheduler-to-azure-functions**: Quartz Scheduler to Azure Functions +- **solace-pubsub-to-azure-service-bus**: Solace PubSub+ to Azure Service Bus +- **spring-batch-to-azure-durable-functions**: Spring Batch to Azure Durable Functions +- **spring-cloud-config-to-azure-app-configuration**: Spring Cloud Config to Azure App Configuration +- **sqlite-to-azure-postgresql**: SQLite to Azure PostgreSQL +- **sybase-ase-to-azure-postgresql**: Sybase ASE to Azure Database for PostgreSQL +- **tibco-ems-jms-to-azure-service-bus**: TIBCO EMS JMS to Azure Service Bus diff --git a/plugins/github-copilot-modernization/skills/create-modernization-plan/tasks-schema.json b/plugins/github-copilot-modernization/skills/create-modernization-plan/tasks-schema.json index 4a73d45..ad2c378 100644 --- a/plugins/github-copilot-modernization/skills/create-modernization-plan/tasks-schema.json +++ b/plugins/github-copilot-modernization/skills/create-modernization-plan/tasks-schema.json @@ -23,6 +23,7 @@ { "$ref": "#/$defs/upgradeTask" }, { "$ref": "#/$defs/containerizationTask" }, { "$ref": "#/$defs/deploymentTask" }, + { "$ref": "#/$defs/securityTask" }, { "$ref": "#/$defs/infrastructureTask" } ] } @@ -62,12 +63,8 @@ "taskBase": { "type": "object", "additionalProperties": false, - "required": ["type", "id", "description", "requirements", "environmentConfiguration"], + "required": ["type", "id", "description", "requirements"], "properties": { - "_comment": { - "type": "string", - "description": "Human guidance for the task template; used by LLM and not required in generated tasks.json." - }, "type": { "type": "string", "description": "Task type identifier." @@ -78,28 +75,35 @@ }, "description": { "type": "string", - "description": "[Brief description of what this task achieves from the user's perspective]" + "description": "[Brief description of what this task achieves from the user's perspective. It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" + }, + "reason": { + "type": "string", + "description": "[Explain why this task is needed, e.g., the motivation, business justification, or technical necessity that drives this task]" }, "requirements": { "type": "string", - "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns)]" + "description": "[The specific requirements for this task including: what to migrate (features, APIs, patterns), constraints (backward compatibility, modules to avoid), target Azure services, and technical preferences (authentication methods, patterns). It should describe high level requirements without dictating implementation details like API calls, package names, or code structure]" }, "environmentConfiguration": { - "type": ["string", "null"], - "description": "[Environment configuration from user input (e.g. endpoint, access id), null if not specified]" - }, - "kbId": { - "type": ["string", "null"], - "description": "[Optional knowledge-base id (matches a solutionId in solution-mapping.json, e.g., 'amqp-rabbitmq-servicebus', 'mi-postgresql', 'java-version-upgrade'). When present, the executor passes this to #appmod-run-task as the kbId parameter (no scenario, no skillId). Carried over from the assessment report's Create Plan input when the originating solution had a backing knowledge base. Leave null when the source scenario has no backing KB (e.g., bare/* placeholder solutions).]" + "type": ["string"], + "description": "[Environment configuration from user input (e.g. endpoint, access id). Omit this field if not specified]" }, "status": { - "type": ["string", "null"], + "type": ["string"], "description": "Task execution status. Only has value after task is executed.", - "enum": [null, "pending", "started", "success", "failed", "skipped"] + "enum": ["pending", "started", "success", "failed", "skipped"] }, "taskSummary": { "type": "string", "description": "Summary of task execution result. Only has value after task is executed." + }, + "dependencies": { + "type": "array", + "description": "[List of task IDs that this task depends on. The task will only be executed after all its dependencies have completed successfully.]", + "items": { + "type": "string" + } } } }, @@ -125,73 +129,46 @@ "required": [ "passBuild", "generateNewUnitTests", - "generateNewIntegrationTests", - "passUnitTests", - "passIntegrationTests", - "securityComplianceCheck" + "passUnitTests" ], "description": "The task success criteria to validate after task execution.", "properties": { "passBuild": { - "type": ["string", "null"], + "type": ["string"], "default": "true", "description": "Project must compile successfully after migration, use default value if user does not specify" }, "generateNewUnitTests": { - "type": ["string", "null"], + "type": ["string"], "default": "false", "description": "Create mock-based unit tests for newly added Azure integration code to ensure test coverage, use default value if user does not specify" }, - "generateNewIntegrationTests": { - "type": ["string", "null"], - "default": "false", - "description": "Create integration tests for Azure service interactions. If Azure resources are provided: tests interact with actual services. If not: tests use mocked Azure SDK clients or test containers, use default value if user does not specify" - }, "passUnitTests": { - "type": ["string", "null"], + "type": ["string"], "default": "true", "description": "All unit tests must pass; mock dependent Azure resources if not provided, use default value if user does not specify" - }, - "passIntegrationTests": { - "type": ["string", "null"], - "default": "false", - "description": "Integration tests must pass when generated. With Azure resources: validates actual connectivity. Without: validates integration logic using mocked clients, use default value if user does not specify" - }, - "securityComplianceCheck": { - "type": ["string", "null"], - "default": "false", - "description": "No known CVEs exist in project dependencies, use default value if user does not specify" } } }, "successCriteriaStatus": { "type": "object", + "not": { + "type": "null" + }, "additionalProperties": false, - "description": "Validation status for each success criteria. Only has values after success criteria validation is complete. true means passed, false means failed.", + "description": "Optional validation status for each success criterion. Omit this field until validation is complete. If present, use true/false string values.", "properties": { "passBuild": { - "type": ["string", "null"], - "description": "Validation status of passBuild criterion. true means passed, false means failed, null means not yet validated." + "type": ["string"], + "description": "Validation status of passBuild criterion. true means passed, false means failed." }, "generateNewUnitTests": { - "type": ["string", "null"], - "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed, null means not yet validated." - }, - "generateNewIntegrationTests": { - "type": ["string", "null"], - "description": "Validation status of generateNewIntegrationTests criterion. true means passed, false means failed, null means not yet validated." + "type": ["string"], + "description": "Validation status of generateNewUnitTests criterion. true means passed, false means failed." }, "passUnitTests": { - "type": ["string", "null"], - "description": "Validation status of passUnitTests criterion. true means passed, false means failed, null means not yet validated." - }, - "passIntegrationTests": { - "type": ["string", "null"], - "description": "Validation status of passIntegrationTests criterion. true means passed, false means failed, null means not yet validated." - }, - "securityComplianceCheck": { - "type": ["boolean", "null"], - "description": "Validation status of securityComplianceCheck criterion. true means passed, false means failed, null means not yet validated." + "type": ["string"], + "description": "Validation status of passUnitTests criterion. true means passed, false means failed." } } }, @@ -201,7 +178,7 @@ { "type": "object", "additionalProperties": false, - "required": ["type", "skills", "successCriteria"], + "required": ["type", "successCriteria"], "properties": { "type": { "const": "transform", @@ -209,7 +186,7 @@ }, "skills": { "type": "array", - "description": "The skills that must be used for this task, e.g., 'migration-rabbitmq-to-servicebus-mi'", + "description": "The skills that will be used for this task, it is started with migration and looks like 'migration-rabbitmq-to-servicebus-mi'", "items": { "$ref": "#/$defs/skill" } }, "successCriteria": { "$ref": "#/$defs/successCriteria" }, @@ -224,17 +201,12 @@ { "type": "object", "additionalProperties": false, - "required": ["type", "skills", "successCriteria"], + "required": ["type", "successCriteria"], "properties": { "type": { "const": "upgrade", "description": "Upgrade task template" }, - "skills": { - "type": "array", - "description": "The skills that must be used for this task, e.g., 'migration-rabbitmq-to-servicebus-mi'", - "items": { "$ref": "#/$defs/skill" } - }, "successCriteria": { "$ref": "#/$defs/successCriteria" }, "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } } @@ -267,11 +239,16 @@ { "type": "object", "additionalProperties": false, - "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool"], + "required": ["type", "targetAzureService", "resourceStatus", "deploymentTool", "skills"], "properties": { "type": { "const": "deployment", - "description": "Deployment task template - Only include if the user explicitly requested deployment." + "description": "Deployment task template - Containerize, provision and deploy the application to Azure. Only include if the user explicitly requested deployment." + }, + "skills": { + "type": "array", + "description": "The deployment skill to use based on targetAzureService: 'azcli-aks-deploy' for Azure Kubernetes Service, 'azcli-containerapp-deploy' for Azure Container Apps, 'azcli-appservice-deploy' for Azure App Service, 'azcli-functionapp-deploy' for Azure Function App, 'azcli-appservicemi-deploy' for Azure App Service with Managed Identity", + "items": { "$ref": "#/$defs/skill" } }, "targetAzureService": { "type": "string", @@ -283,13 +260,35 @@ }, "deploymentTool": { "type": "string", - "description": "Deployment tool name.", - "const": "bicep" + "description": "Infrastructure as Code tool type. Default to 'terraform' for aks, 'bicep' for other services if not specified.", + "enum": ["bicep", "terraform"] } } } ] }, + "securityTask": { + "allOf": [ + { "$ref": "#/$defs/taskBase" }, + { + "type": "object", + "additionalProperties": false, + "required": ["type", "successCriteria"], + "properties": { + "type": { + "const": "security", + "description": "Security task template - Include when security remediation, vulnerability scanning, or compliance checks are required." + }, + "cveReport": { + "type": ["string"], + "description": "Path to final-cve-report.json. Only has value after CVE checking is complete." + }, + "successCriteria": { "$ref": "#/$defs/successCriteria" }, + "successCriteriaStatus": { "$ref": "#/$defs/successCriteriaStatus" } + } + } + ] + }, "infrastructureTask": { "allOf": [ { "$ref": "#/$defs/taskBase" }, @@ -302,11 +301,6 @@ "const": "infrastructure", "description": "Infrastructure task template - Generate IaC files (Bicep or Terraform) to provision Azure resources." }, - "skills": { - "type": "array", - "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", - "items": { "$ref": "#/$defs/skill" } - }, "iacType": { "type": "string", "description": "Infrastructure as Code tool type.", @@ -315,6 +309,11 @@ "provision": { "type": "boolean", "description": "Whether to provision Azure resources after generating IaC files." + }, + "skills": { + "type": "array", + "description": "The skill used for this task, e.g., 'infrastructure-bicep-generation' or 'infrastructure-terraform-generation'", + "items": { "$ref": "#/$defs/skill" } } } } diff --git a/plugins/github-copilot-modernization/skills/dag-generation/references/task-catalog.md b/plugins/github-copilot-modernization/skills/dag-generation/references/task-catalog.md index a4088e9..8ac0b0a 100644 --- a/plugins/github-copilot-modernization/skills/dag-generation/references/task-catalog.md +++ b/plugins/github-copilot-modernization/skills/dag-generation/references/task-catalog.md @@ -110,7 +110,7 @@ LLM uses this to select task fragments for DAG generation. Each fragment is `{de - **skip when**: Backend-only migration; no frontend changes; same-framework upgrade ### smoke-test -- **desc**: Independent build and startup verification from reviewer perspective. Run the single build command that covers every module in this project, start the application, verify it responds on expected port. Record results (build status, startup time, HTTP status) in artifact. This is NOT testing — it is a gate check that the deliverable is minimally viable. +- **desc**: Independent build and startup verification from reviewer perspective. Run the project's root-level full build and emit a `## Smoke Test Verdict` block into the artifact. Execution rules (full-build requirement, frozen install, verdict block format) are in the worker agent's **Smoke-Test Build Verification** section. - **scope**: global - **after**: all execute-phase tasks - **when**: Always selected when execute-phase tasks exist diff --git a/plugins/github-copilot-modernization/skills/data-architecture/SKILL.md b/plugins/github-copilot-modernization/skills/data-architecture/SKILL.md new file mode 100644 index 0000000..618a3f6 --- /dev/null +++ b/plugins/github-copilot-modernization/skills/data-architecture/SKILL.md @@ -0,0 +1,274 @@ +--- +name: data-architecture +description: Generate data architecture and persistence layer documentation with data model diagram +--- + +# Data Architecture & Persistence Layer + +Analyze the project to document database configuration, entity models, data ownership boundaries, repository interfaces, and caching strategies. Generate a Mermaid ER diagram showing entity relationships. Save to `.github/modernize/assessment/engines/facts/data-architecture.md`. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Scope Boundaries — Avoid Redundancy with Other Skills + +This skill is part of a set of four complementary assessment skills. To avoid content duplication across their output documents, observe these scope rules: + +- **Introduction**: Write a 1-2 sentence intro focused on the data layer (number of entities, database types, ORM). Do NOT restate the application's overall architecture type, web framework, or API surface — those are covered by other skills. +- **Configuration property keys/values** (e.g., `spring.jpa.hibernate.ddl-auto`, `spring.sql.init.*`) are owned by the `configuration-inventory` skill. In the Database Configuration table, describe the *behavior* (e.g., "Hibernate does not manage schema; SQL scripts are authoritative") but do NOT list raw property key-value pairs. Reference `configuration-inventory.md` for the full property inventory. +- **API endpoints and HTTP methods** are owned by the `api-service-contracts` skill. Do NOT list controller endpoints or HTTP paths. Repository methods are in scope for this skill; controller routes are not. +- **Business workflow steps and validation rules** are owned by the `business-workflows` skill. Do NOT describe multi-step business processes or enumerate validation constraints. When documenting entity relationships (cascade, fetch), focus on the persistence/ORM implications, not the business process flow. +- **Deployment configurations** (Docker Compose, K8s, profiles) are owned by the `configuration-inventory` skill. Mention database profiles only in the Database Configuration table to identify which DB is used per profile — do NOT describe Docker Compose services, K8s manifests, or deployment targets in detail. + +## Execution Steps + +### Step 1: Generate Database Configuration Section + +Extract database configuration from project files, **per profile/environment**, and produce the complete `## Database Configuration` section: + +- Database types: HSQLDB, MySQL, PostgreSQL, MongoDB, SQL Server, Oracle, SQLite, CosmosDB, DynamoDB +- **Per-profile configuration**: identify which database is used in each profile (e.g., HSQLDB for `default`/dev in-memory testing, MySQL for `production`/`mysql` profile) +- Database drivers per profile (e.g., `mysql-connector-java` for production, `hsqldb` for development) +- Connection configuration: connection strings, JDBC URLs, pooling settings (HikariCP, connection pool size) +- Migration tools: Flyway, Liquibase, EF Migrations, Alembic, Prisma Migrate, Knex migrations +- Schema management: DDL auto-generation settings (`spring.jpa.hibernate.ddl-auto`), schema versioning, initial schema scripts +- Seed data: `data.sql`, `import.sql`, seed migration files, or programmatic data seeding + +### Step 2: Generate Data Ownership per Service Section + +Determine table/entity ownership across modules/services and produce the complete `## Data Ownership per Service` section. Scope is strictly the per-service ownership table — high-level data boundary discussion belongs in Step 6. + +For each module/service, identify: + +- Which tables/entities it owns (bounded context analysis) +- ORM framework used (e.g., Hibernate, EF Core, MyBatis, Mongoose) +- Caching layer used by this service (if any) +- Brief notes (e.g., outbox table, schema-per-service) + +> Do NOT include shared-vs-isolated data store summary, cross-service data access patterns, or read/write/CQRS observations here — those belong in the `## Data Ownership Boundaries` section (Step 6). + +### Step 3: Generate Entity Model Section + +Scan source code for data access patterns and ORM entities, then produce the complete `## Entity Model` section: + +**Analysis:** +- Java: JPA/Hibernate entities (`@Entity`, `@Table`), Spring Data repositories (`JpaRepository`, `CrudRepository`), MyBatis mappers, JDBC templates +- .NET: EF Core `DbContext`, EF Core entities, Dapper, ADO.NET +- JavaScript/TypeScript: Mongoose models/schemas, Sequelize models, TypeORM entities, Prisma schema, Knex migrations + +Identify: +- Entity/model classes with their fields, types, and constraints — note the source file path for each entity +- Transaction management annotations/configuration (`@Transactional`, `TransactionScope`, etc.) +- Bidirectional vs unidirectional relationship mappings (e.g., `owner.addPet(pet)` establishing parent-child links) + +**Diagram — Mermaid `erDiagram`:** +- Show primary entities with key fields (PK, FK) +- Use standard cardinality notation: `||--o{` (one-to-many), `||--||` (one-to-one), `}o--o{` (many-to-many) +- Group related entities logically +- Include relationship labels +- Annotate which service owns each entity group (use comments or subgraph labels) + +Example: + +~~~mermaid +erDiagram + Owner ||--o{ Pet : "has" + Pet ||--o{ Visit : "has" + Pet }o--|| PetType : "is of" + Vet }o--o{ Specialty : "has" + Owner { + int id PK + string firstName + string lastName + string address + string city + string telephone + } + Pet { + int id PK + string name + date birthDate + int ownerId FK + int typeId FK + } + PetType { + int id PK + string name + } + Visit { + int id PK + int petId FK + date visitDate + string description + } + Vet { + int id PK + string firstName + string lastName + } + Specialty { + int id PK + string name + } +~~~ + +### Step 4: Generate Key Repository Methods Section + +For each service/module, document the key repository interfaces and produce the complete `## Key Repository Methods` section: + +- Repository interface name, entity type, and source file path +- Standard CRUD methods inherited from base interface +- Custom query methods with their signatures and purposes — especially: + - Bulk/batch queries (e.g., `findByPetIdIn(Collection)`) used for cross-service aggregation + - Custom finders with derived query methods + - Named queries or `@Query`-annotated methods + - Raw SQL or stored procedure calls +- Query method parameters and return types + +### Step 5: Generate Caching Strategy Section + +Identify caching layers and configuration and produce the complete `## Caching Strategy` section: + +- Cache providers: EhCache, Redis, Caffeine, Spring Cache (`@Cacheable`, `@CacheEvict`), MemoryCache, IDistributedCache +- Cache configuration: TTL, eviction policies, cache regions/names +- Cache-aside, read-through, write-through, write-behind patterns +- Session caching, query result caching, second-level cache (Hibernate) +- Rationale for caching decisions (e.g., "veterinarian data is read frequently but changes rarely") +- JSR-107 (JCache) / `cache-api` usage and provider binding + +### Step 6: Generate Data Ownership Boundaries Section + +Document data-store topology and cross-service access semantics, plus data classification, then produce the complete `## Data Ownership Boundaries` section (including the `### Data Classification & Sensitivity` subsection): + +**Boundaries:** +- Shared vs isolated data stores (shared database, database-per-service, logical separation within shared DB) +- Cross-service data access patterns: how one service queries another service's data (direct DB access vs REST API calls vs batch/bulk query methods such as `findByPetIdIn(...)` that enable gateway-level aggregation) +- Read/write patterns and CQRS observations across services + +**Data Classification & Sensitivity (`### Data Classification & Sensitivity` subsection):** +- Identify whether stored data contains sensitive categories — PII (names, addresses, phone numbers, emails), PHI (health records), PCI (payment card data) +- For each sensitive category found, note whether encryption-at-rest, data masking, or field-level access controls are in place +- If absent, state this explicitly (e.g., "Owner entity stores PII (firstName, lastName, address, telephone); no encryption-at-rest or masking configured") + +### Step 7: Save Output + +Save to `.github/modernize/assessment/engines/facts/data-architecture.md` with this exact structure: + +``` +# Data Architecture & Persistence Layer + +A brief introduction (1-2 sentences) summarizing the data layer. + +## Database Configuration + +[Table: Service/Module | DB Type | Profile | Driver | Connection | Migration Tool] + +## Data Ownership per Service + +[Table: Service | Tables Owned | ORM Framework | Caching | Notes] + +## Entity Model + +< Mermaid erDiagram here > + +## Key Repository Methods + +[Table: Service | Repository | Notable Methods | Purpose] + +## Caching Strategy + +[Table or description of caching layers, providers, TTL, patterns, and rationale] + +## Data Ownership Boundaries + +[Description of shared vs isolated data stores, cross-service data access patterns, and aggregation enablers] + +### Data Classification & Sensitivity + +[Table: Entity | Sensitive Fields | Classification (PII/PHI/PCI/None) | Controls in Place] +[If no sensitive data found: "No PII, PHI, or PCI data detected in entity model."] +``` + +## Scaling Rules + +- If the project has **more than 30 entities**, aggregate minor entities and show only the core domain model (15-20 key entities) +- Keep the ER diagram under **40 entities** to ensure readability and GitHub rendering compatibility +- For multi-module projects, focus on inter-module entity relationships and data boundaries +- Collapse join tables into relationship annotations rather than showing them as separate entities +- In the repository methods table, focus on non-CRUD custom methods; omit standard inherited methods + +## Mermaid Syntax Rules + +Use `erDiagram`. The diagram must parse cleanly under the official Mermaid grammar — anything outside it crashes the whole diagram, not just the offending line. Stay inside the minimal legal subset below. + +### Attribute grammar + +Every attribute line inside an entity body MUST follow exactly this shape: + +``` + [] [""] +``` + +- `` and ``: single tokens, plain text (letters, digits, underscore). No spaces, no backticks, no `@#$%&`. +- ``: optional. **Exactly one of** `PK`, `FK`, `UK` — never two, never combined. Compound tokens like `PK_FK`, `PKFK`, `PK/FK` are not part of the grammar. +- ``: optional, must be a double-quoted string. The description is free text BUT must not contain `{`, `}`, or unescaped double quotes. + +### Canonical attribute examples (copy these shapes) + +``` +int Id PK +string Name +int OwnerId FK +int InstructorId PK "also FK to Person (shared PK)" +int CourseId PK "composite PK; FK to Course" +int StudentId PK "composite PK; FK to Person" +string Email UK "unique" +decimal Budget "money column" +bytes RowVersion "concurrency token" +``` + +Rule of thumb for **composite primary keys whose columns are also foreign keys** (join tables like `CourseAssignment`, shared-PK one-to-one tables like `OfficeAssignment`): mark every column as `PK` only, and note the FK role in the quoted description. The FK relationship itself is already conveyed by the cardinality arrows between entities — duplicating it as a second key marker is what crashes the parser. + +### Relationships + +- Cardinality is written as `--`, where each side independently picks one of: + - `||` — exactly one + - `|o` / `o|` — zero or one + - `}o` / `o{` — zero or many + - `}|` / `|{` — one or many + The "open" side of `o`/`}`/`{` always faces inward (toward the `--`). All resulting combinations are legal, e.g. `||--o{` (one-to-many), `||--||` (one-to-one), `}o--o{` (many-to-many), `}o--||` (many-to-one), `|o--o{` (zero-or-one to many), `||--o|` (one to zero-or-one). +- Always quote the label: `Owner ||--o{ Pet : "has"`. +- The label is free text but must not contain `{`, `}`, or unescaped double quotes. + +### Hard prohibitions (these crash the whole diagram, not just one line) + +1. **No `{` or `}` inside any quoted description or label.** Mermaid's ER parser treats `{` as the entity-body opener even inside quotes. Use `<...>` for placeholders, or rephrase in plain words. + - ❌ `string Key PK "Redis key /basket/{BuyerId}"` + - ✅ `string Key PK "Redis key /basket/"` +2. **No more than one key marker per attribute.** See the grammar above. +3. **No backticks, no special characters (`@#$%&`) in entity names, attribute names, or types.** +4. **No `\n` anywhere in the diagram.** The literal `\n` escape was removed in modern Mermaid (>= 9.x) and triggers "Syntax error in text". Keep every quoted description on a single line; if you need to express more, shorten the prose or split it across multiple attributes. + - ❌ `string Roles "comma-separated\nROLE_USER, ROLE_ADMIN"` + - ✅ `string Roles "comma-separated; ROLE_USER, ROLE_ADMIN"` + +### Self-check before emitting the diagram + +Before writing the ```` ```mermaid ```` block, walk every attribute line and verify it matches ` [] [""]` with **at most one** key token. Walk every quoted string and verify it contains no `{` or `}`. If a description needs to express two key roles (e.g., composite PK that is also FK), encode the second role as plain text inside the quoted description — never as a second token before the quote. + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No data access layer found**: Output: `> ERROR: No recognized data access patterns or entities found at {workspace-path}. Verify the path is correct.` +- **Insufficient info**: Generate a best-effort diagram from available data. Add a note: `> Note: Some entities or relationships could not be fully identified.` + +## Success Criteria + +- Database configuration table lists all discovered databases with type, profile, driver, and migration tools +- Data ownership table maps each service to its owned tables, ORM, and caching layer +- Mermaid ER diagram renders correctly showing entity relationships with cardinality and key fields +- Repository methods table documents custom query methods with purposes, especially cross-service aggregation enablers +- Caching strategy section describes cache providers, patterns, and rationale +- Data ownership boundaries describe shared vs isolated stores and cross-service data access patterns +- Data Classification & Sensitivity table identifies PII/PHI/PCI fields and documents presence or absence of controls +- File saved to `.github/modernize/assessment/engines/facts/data-architecture.md` diff --git a/plugins/github-copilot-modernization/skills/dependency-map/SKILL.md b/plugins/github-copilot-modernization/skills/dependency-map/SKILL.md new file mode 100644 index 0000000..6b74fab --- /dev/null +++ b/plugins/github-copilot-modernization/skills/dependency-map/SKILL.md @@ -0,0 +1,196 @@ +--- +name: dependency-map +description: Generate dependency map diagram from project build files +--- + +# Dependency Map + +Analyze project build and package files to generate a visual map of all external dependencies grouped by functional category. Save to `.github/modernize/assessment/engines/facts/dependency-map.md`. + +This skill focuses exclusively on **declared external dependencies** (libraries, frameworks, packages). For internal application structure and component relationships, see the `architecture-diagram` skill. + +## Input Parameters + +- `workspace-path` (optional): Path to the project to analyze (defaults to current directory) + +## Execution Steps + +### Step 1: Generate Dependencies Section + +Analyze build files and produce the complete `## Dependencies` section in one pass: + +**Analysis — examine only build and package management files** (do NOT scan source code — that is the `architecture-diagram` skill's job): + +- Java: pom.xml, build.gradle, settings.gradle, gradle.properties, gradle lockfiles +- .NET: *.csproj, Directory.Build.props, packages.config, Directory.Packages.props +- JavaScript/TypeScript: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml + +For each dependency extract: +- Group/package name and artifact name +- Declared version (or version range) +- Scope (compile, runtime, test, provided) + +Also detect: +- Parent POM / BOM imports (Java) +- Central package management (.NET Directory.Packages.props) +- Transitive dependencies where visible from lock files or BOM + +**Categorize** dependencies into functional groups: + +| Category | Examples | +|----------|----------| +| Web Frameworks | Spring Web, ASP.NET Core MVC, JAX-RS | +| Database / ORM | Hibernate, Entity Framework, JDBC drivers | +| Messaging | Kafka client, RabbitMQ, Azure Service Bus | +| Caching | Redis, EhCache, MemoryCache | +| Logging | SLF4J, Log4j, Serilog, NLog | +| Security | Spring Security, Microsoft.Identity, OAuth libs | +| Observability | Micrometer, OpenTelemetry, Application Insights | +| Utilities | Guava, Apache Commons, Lombok, AutoMapper | + +Rules: +- Exclude test-scoped dependencies (JUnit, xUnit, Mockito, etc.) from the main diagram and Dependency Summary table — they are not relevant for modernization planning +- If a dependency doesn't fit any category, put it under "Utilities" +- Collect test-scoped dependencies separately for the Test Dependencies section (Step 2) + +**Diagram — Mermaid `flowchart LR`:** +- Application as the central left-side node +- One `subgraph` per functional category +- Each dependency as a node showing name and version: `Lib["Library Name v1.2.3"]` +- Arrows from Application to each category subgraph +- If a BOM/parent POM manages versions, show it as a separate node linked to the dependencies it governs + +Example: + +~~~mermaid +flowchart LR + App["MyApplication"] + + subgraph Web["Web Frameworks"] + SpringMVC["Spring MVC 5.3.x"] + Thymeleaf["Thymeleaf 3.0"] + end + subgraph DB["Database / ORM"] + Hibernate["Hibernate 5.6"] + PgDriver["PostgreSQL Driver 42.6"] + end + subgraph Messaging + Kafka["Kafka Client 3.4"] + end + subgraph Cache["Caching"] + Redis["Jedis 4.3"] + end + subgraph Log["Logging"] + SLF4J["SLF4J 1.7"] + Logback["Logback 1.2"] + end + subgraph Sec["Security"] + SpringSec["Spring Security 5.7"] + end + subgraph Util["Utilities"] + Lombok["Lombok 1.18"] + Jackson["Jackson 2.14"] + end + + App -->|"web"| Web + App -->|"persistence"| DB + App -->|"messaging"| Messaging + App -->|"caching"| Cache + App -->|"logging"| Log + App -->|"security"| Sec + App -->|"utilities"| Util + SLF4J -.->|"implementation"| Logback +~~~ + +**Textual explanations (write immediately after the diagram):** +- **Dependency Summary table**: Category | Count | Key Libraries | Notes (e.g., Web Frameworks | 2 | ASP.NET MVC 5.2.7, Razor 3.2.7 | Legacy MVC stack on .NET Framework) +- **Version & Compatibility Risks**: A short paragraph highlighting dependencies that are outdated, end-of-life, or have known migration concerns (e.g., ".NET Framework 4.7.2 is in maintenance mode; Entity Framework 6 has a migration path to EF Core") +- **Notable Observations**: 2-4 bullet points on anything noteworthy — duplicate functionality across libraries, deprecated packages, security-sensitive dependencies, or unusually large transitive trees + +### Step 2: Generate Test Dependencies Section + +Collect all test-scoped dependencies (excluded from the main diagram) and produce the complete `## Test Dependencies` section: + +- List detected test frameworks and supporting libraries with their versions (e.g., JUnit 5, Mockito, AssertJ, Testcontainers, xUnit, Jest) +- Report the total number of test-scope dependencies +- Note any test infrastructure concerns (e.g., outdated test framework version, missing contract-testing library, no integration test framework detected) + +### Step 3: Save Output + +Save to `.github/modernize/assessment/engines/facts/dependency-map.md` with this exact structure: + +``` +# Dependency Map + +A brief introduction (1-2 sentences) stating project name and total dependency count. + +## Dependencies + +< Mermaid flowchart LR here > + +### Dependency Summary + +[Table: Category | Count | Key Libraries | Notes] + +### Version & Compatibility Risks + +[Short paragraph on outdated or end-of-life dependencies] + +### Notable Observations + +[2-4 bullet points on noteworthy findings] + +## Test Dependencies + +[Table: Framework | Version | Notes] + +Total test-scope dependencies: N +[1-2 sentences on test infrastructure observations, or "No test dependencies detected."] +``` + +## Scaling Rules + +- If the project has **more than 50 declared dependencies**, collapse minor utilities into a single aggregate node (e.g., `Utils["12 utility libraries"]`) and only show individually the top dependencies by importance +- Keep the diagram under **40 nodes** to ensure readability and GitHub rendering compatibility +- For multi-module projects (e.g., multi-module Maven/Gradle, multi-project .sln), show shared dependencies once and module-specific dependencies grouped by module + +## Mermaid Syntax Rules + +The diagram must parse cleanly under **Mermaid >= 9.x**. Anything outside the legal subset crashes the entire diagram with `Syntax error in text`. + +- Use `flowchart LR` +- Avoid special characters (`@`, `#`, `$`, `%`, `&`) in node labels — use plain text +- Always quote arrow labels with double quotes: `-->|"label"|` +- Use `subgraph` for grouping, with a display name in quotes if it contains spaces +- Use `-.->` (dotted arrow) for transitive/indirect relationships +- Verify all node IDs are unique across the entire diagram + +### Line breaks in node labels — HARD RULE + +- **NEVER use `\n` for line breaks inside node labels.** The literal `\n` escape was removed in modern Mermaid and is the #1 cause of "Syntax error in text". +- **Use `
` instead**: `Node["First line
Second line"]`. +- Prefer single-line labels; move detail into the inventory table. +- ❌ `Spring["Spring Boot\n2.5.12"]` +- ✅ `Spring["Spring Boot
2.5.12"]` or `Spring["Spring Boot 2.5.12"]` + +### Self-check before emitting each ```mermaid block + +1. Search the block for the two characters `\n` — replace each with `
`. Zero `\n` must remain. +2. Confirm every node ID is unique and every `subgraph` is closed by `end`. +3. Confirm every arrow label is double-quoted. + +## Error Handling + +- **Unsupported project type**: Output a single line: `> ERROR: Unsupported project type. This skill supports Java, .NET, JavaScript, and TypeScript projects only.` +- **No build files found**: Output: `> ERROR: No recognized build files found at {workspace-path}. Verify the path is correct.` +- **Incomplete dependency info**: Generate a best-effort diagram from available data. Add a note inside the diagram: `Note["Some dependencies could not be fully resolved"]` + +## Success Criteria + +- Mermaid diagram renders correctly with dependencies grouped by functional category +- Each dependency shows name and version +- Dependency Summary table lists categories with counts and key libraries +- Version & Compatibility Risks paragraph highlights outdated or end-of-life dependencies +- Notable Observations lists 2-4 noteworthy findings +- Test Dependencies section lists detected test frameworks with versions and total count +- File saved to `.github/modernize/assessment/engines/facts/dependency-map.md` diff --git a/plugins/github-copilot-modernization/skills/quality-gates/references/gate-completeness.md b/plugins/github-copilot-modernization/skills/quality-gates/references/gate-completeness.md index b121cb2..0e59a07 100644 --- a/plugins/github-copilot-modernization/skills/quality-gates/references/gate-completeness.md +++ b/plugins/github-copilot-modernization/skills/quality-gates/references/gate-completeness.md @@ -2,10 +2,20 @@ **Load**: constitution, feature spec, plan.md, implementation files, all 3 checkpoints (spec-to-plan.yaml, plan-to-tasks.yaml, tasks-to-impl.yaml) +## Build Verdict (blocking — evaluate FIRST) + +Judge build status ONLY from the `## Smoke Test Verdict` block in the smoke-test artifact. +A worker's prose ("build passed") or self-applied label is NOT evidence. Read `build_command`, `install_command`, and the returncodes directly. + +1. If the `## Smoke Test Verdict` block is missing, or `build_command`/`returncode` is absent → CRITICAL. +2. If `returncode` != 0 → CRITICAL. +3. The build counts ONLY if it is the project's full build, unmodified: run from the repo root, covering every module (`covers_all_modules: yes`), and — for a JS/TS project — preceded by a frozen install (`npm ci` / `yarn install --immutable` (classic `--frozen-lockfile`) / `pnpm install --frozen-lockfile`) with `install_returncode == 0`. → CRITICAL if, for a JS/TS project, `install_command`/`install_returncode` is missing, the install is non-frozen or scoped to one package, or `install_returncode` != 0; or if `build_command` narrows scope, skips a module, or downgrades the build. Judge by this rule, not by matching a fixed token list; e.g. maven `-pl`/`-am`, `--filter`/`-w`/`cd && build` (single package), `--no-frozen-lockfile`, and `--mode=skip-build` all fail it. (`install_*` may be `n/a` only for non-JS/TS.) +4. PASS the build check only when all returncodes are 0 AND `build_command` is the project's root-level full build AND `covers_all_modules: yes`. Otherwise CRITICAL → create a remediation task to re-run smoke-test with the full build; do NOT advance dependents. + ## Checklist - [ ] All plan items have corresponding implementation files → *CRITICAL if missing* -- [ ] Build succeeds, tests pass → *CRITICAL if failure* +- [ ] Build succeeds, tests pass — build half: see **Build Verdict** section above; tests half: verify test results in implementation artifacts → *CRITICAL if failure* - [ ] Constitution followed in implementation → *CRITICAL if violated* - [ ] All P1 requirements fulfilled → *CRITICAL if unmet* - [ ] Every implementation task artifact includes `## Test Results` with pass/fail/skip counts and test command → *CRITICAL if missing or failed > 0* @@ -24,7 +34,7 @@ - `checkpoints/tasks-to-impl.yaml` 2. Check plan.md Requirement Mapping table Implementation Evidence column 3. Verify all referenced implementation files exist -4. Run build and tests +4. Evaluate build per the **Build Verdict** section (blocking — must be done before advancing); verify tests per implementation task artifacts 5. Verify constitution compliance in code 6. Confirm P1 requirements are implemented 7. For brownfield (migration and rewrite): verify functional equivalence per `references/functional-equivalence.md` diff --git a/plugins/github-copilot-modernization/skills/team-charters/SKILL.md b/plugins/github-copilot-modernization/skills/team-charters/SKILL.md index 9462afd..84e3c20 100644 --- a/plugins/github-copilot-modernization/skills/team-charters/SKILL.md +++ b/plugins/github-copilot-modernization/skills/team-charters/SKILL.md @@ -14,7 +14,7 @@ Defines the mission, ownership, core principles, quality bar, and (for most role | Role | Mission | Charter | |---|---|---| -| **architect** | Own the technical blueprint: how the system is built, how it should be rebuilt, and whether the implementation follows the design | `references/architect.md` | +| **architect** | Own the technical blueprint: how the system is built, how it should be rebuilt, whether the implementation follows the design, and build verification (smoke test) | `references/architect.md` | | **backend** | Own the server-side implementation: build the logic that powers the product | `references/backend.md` | | **dba** | Own the data layer: make sure data is modeled correctly, stored safely, and migrates reliably | `references/dba.md` | | **devops** | Own CI/CD pipelines, deployment automation, and operational infrastructure | `references/devops.md` | diff --git a/plugins/github-copilot-modernization/skills/team-charters/references/architect.md b/plugins/github-copilot-modernization/skills/team-charters/references/architect.md index a1411c6..d0605a0 100644 --- a/plugins/github-copilot-modernization/skills/team-charters/references/architect.md +++ b/plugins/github-copilot-modernization/skills/team-charters/references/architect.md @@ -2,7 +2,7 @@ ## Mission -Own the technical blueprint of the system: architecture design, API contracts, module boundaries, and migration strategy. Turn requirements into a design that implementation roles can build from. +Own the technical blueprint of the system: architecture design, API contracts, module boundaries, migration strategy, and build verification (smoke test). Turn requirements into a design that implementation roles can build from. ## You Own @@ -13,7 +13,7 @@ Own the technical blueprint of the system: architecture design, API contracts, m - **Smoke test** — independent build and startup verification from reviewer perspective: 1. **Full build** — run the single build command that covers every module in this project. Test coverage belongs to the tester role. 2. **Startup** — launch the application, verify it binds to the expected port and responds to HTTP. - 3. **Verdict** — record: build exit code, any plugin failures, startup time, HTTP status. Broken build or failed quality gate = CRITICAL blocker, escalate immediately. + 3. **Verdict** — record: build exit code, any plugin failures, startup time, HTTP status. Broken build or failed quality gate = CRITICAL blocker, escalate immediately. Dependency conflicts (peer dependency mismatches, unresolved versions) are HIGH even if the current package manager tolerates them — they indicate version incompatibility that must be fixed. ## Core Principle