Demo Walkthrough — LegacyShop, net6.0 → net10.0
A real run of the ai-migration-kit pipeline (2026-07-22), executed with RoselineMCP against a scratch copy of samples/LegacyShop. Every number and diff below is captured tool output, not a mock-up.
Result first
| Before | After | |
|---|---|---|
| Target framework | net6.0 (out of support) | net10.0 (LTS) |
RoselineMCP analyze_solution (≥ Warning) | 0 errors / 2 warnings | 0 errors / 0 warnings |
| Tests | 6/6 green (net6.0) | 6/6 green (net10.0) |
| Runtime output | total: 116,01 / Shipped | identical |
Phase 1 — Assess
analyze_solution (severity ≥ Warning) on the legacy solution:
{"projects": 3, "diagnosticSummary": {"error": 0, "warning": 2},
"topDiagnostics": [
{"id": "RCS1102", "file": "Program.cs", "message": "Make class static"},
{"id": "SYSLIB0014", "file": "PriceCatalogClient.cs",
"message": "'WebClient.WebClient()' is obsolete ... Use HttpClient instead."}]}
Written to migration/assessment.md — risk map: net6.0 EOL (high), WebClient (medium). Zero files modified.
Field note: the very first
analyze_solutionreturned 344 bogus “System not found” errors — the copy had never been restored. Lesson encoded in the phase guide: restore before you analyze.
Phase 2 — Baseline
dotnet build green, dotnet test: 6/6 passed. Gate contract recorded in migration/baseline.md: errors = 0, warnings ≤ 2, tests ≥ 6.
Phase 3 — Retarget
All three csprojs bumped to net10.0; test stack to Test SDK 17.14.1, xunit 2.9.3, runner 3.1.1. Rebuild: 0 errors, 1 warning left (SYSLIB0014 — NETSDK1138 disappeared with the TFM). Tests: 6/6 on net10.0.
Field note (added in 1.10.0): this run predates the phase-5 xunit v2 → v3 item, so it landed on the v2 line — as the phase-3 guide prescribed at the time. That is exactly the accidental outcome 1.10.0 turns into a decision:
dotnet list package --outdatedproposesxunit2.9.3 and can never proposexunit.v3, because the package identifier changes. The numbers above are the real run and are left untouched; seeskills/migrate-legacy/references/xunit-v3-migration.md.
Phase 4 — Remediate
list_diagnostics on Domain: 62 diagnostics — 1 warning (SYSLIB0014) + info-level with registered fixes (suggestedFixableIds: ["RCS1015","RCS1058","RCS1170"]).
Judgment fix — WebClient → shared HttpClient via edit_member (preview, then apply):
- using (var client = new WebClient())
+ return Http.GetStringAsync(url).GetAwaiter().GetResult();
- {
- return client.DownloadString(url);
- }
}
+
+ private static readonly HttpClient Http = new HttpClient();
Bulk fixes — one apply_fixes call, preview inspected, then applied: "Applied 16 fixes to 4 files" (RCS1015 nameof ×9, RCS1058 compound assignment ×2, RCS1170 read-only auto-property ×5), plus RCS1102 (static class Program) in App. Gate: 0 warnings, 0 errors, 6/6 tests.
Phase 5 — Modernize (safe set)
ImplicitUsings+Nullableenabled in Domain → rebuild: 0 new warnings (constructors already guarantee assignment).- Async end-to-end:
find_referencesonDownloadCatalog→totalReferences: 0(safe) →rename_symbol→DownloadCatalogAsync(preview matched the reference count, then applied) →edit_membermade it trulyasync Task<string>withawait ... ConfigureAwait(false). - Gate: build + tests green,
dotnet runoutput identical to baseline.
Phase 6 — Verify
Final analyze_solution:
{"projects": 3, "diagnosticSummary": {"error": 0, "warning": 0, "info": 0, "hidden": 0}}
migration/report.md written; migration branch history is one commit per green gate:
2426ae2 migration: phase 6 verified — report
3693776 migration: phase 5 modernize (ImplicitUsings+Nullable, DownloadCatalogAsync)
272dcf3 migration: phase 4 bulk fixes via apply_fixes (x16 + x1)
c93884d migration: phase 4 replace WebClient with shared HttpClient (SYSLIB0014)
21a4f14 migration: phase 3 retarget net6.0 -> net10.0
974a41d migration: phase 1-2 assess + baseline
Spec success criteria — checked
- Plugin manifests valid JSON;
/migrate,/migrate-assess,/migrate-verifypresent incommands/. - Every phase reference names its exact RoselineMCP calls (verified by grep).
- Demo migrated LegacyShop net6.0 → net10.0: build green, 6/6 tests, 0/0 diagnostics vs 0/2 baseline, identical runtime output.
Reproduce it
cp -r samples/LegacyShop /tmp/shop && cd /tmp/shop && git init && git add -A && git commit -m legacy
dotnet restore # ← before any RoselineMCP analysis
claude
> /migrate