diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/assessment.md b/.github/upgrades/scenarios/dotnet-version-upgrade/assessment.md
index fa750206..42d2099c 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/assessment.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/assessment.md
@@ -4,7 +4,7 @@ This document provides a comprehensive overview of the projects and their depend
## Table of Contents
-- [Executive Summary](#executive-Summary)
+- [Executive Summary](#executive-summary)
- [Highlevel Metrics](#highlevel-metrics)
- [Projects Compatibility](#projects-compatibility)
- [Package Compatibility](#package-compatibility)
@@ -27,7 +27,6 @@ This document provides a comprehensive overview of the projects and their depend
- [MyBlog\tests\Web.Tests.Integration\Web.Tests.Integration.csproj](#myblogtestswebtestsintegrationwebtestsintegrationcsproj)
- [MyBlog\tests\Web.Tests\Web.Tests.csproj](#myblogtestswebtestswebtestscsproj)
-
## Executive Summary
### Highlevel Metrics
@@ -153,6 +152,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart LR
P1["📦 AppHost.csproj
net10.0"]
P2["📦 Domain.csproj
net10.0"]
@@ -195,6 +195,7 @@ flowchart LR
## Project Details
+
### MyBlog\src\AppHost\AppHost.csproj
#### Project Info
@@ -217,6 +218,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph upstream["Dependants (2)"]
P5["📦 AppHost.Tests.csproj
net10.0"]
@@ -252,6 +254,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***596*** | |
+
### MyBlog\src\Domain\Domain.csproj
#### Project Info
@@ -274,6 +277,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph upstream["Dependants (6)"]
P4["📦 Web.csproj
net10.0"]
@@ -313,6 +317,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***254*** | |
+
### MyBlog\src\ServiceDefaults\ServiceDefaults.csproj
#### Project Info
@@ -335,6 +340,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph upstream["Dependants (2)"]
P1["📦 AppHost.csproj
net10.0"]
@@ -362,6 +368,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***138*** | |
+
### MyBlog\src\Web\Web.csproj
#### Project Info
@@ -384,6 +391,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph upstream["Dependants (5)"]
P1["📦 AppHost.csproj
net10.0"]
@@ -428,6 +436,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***5012*** | |
+
### MyBlog\tests\AppHost.Tests\AppHost.Tests.csproj
#### Project Info
@@ -450,6 +459,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["AppHost.Tests.csproj"]
MAIN["📦 AppHost.Tests.csproj
net10.0"]
@@ -474,6 +484,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***2830*** | |
+
### MyBlog\tests\Architecture.Tests\Architecture.Tests.csproj
#### Project Info
@@ -496,6 +507,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["Architecture.Tests.csproj"]
MAIN["📦 Architecture.Tests.csproj
net10.0"]
@@ -523,6 +535,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***405*** | |
+
### MyBlog\tests\Domain.Tests\Domain.Tests.csproj
#### Project Info
@@ -545,6 +558,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["Domain.Tests.csproj"]
MAIN["📦 Domain.Tests.csproj
net10.0"]
@@ -569,6 +583,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***724*** | |
+
### MyBlog\tests\Web.Tests.Bunit\Web.Tests.Bunit.csproj
#### Project Info
@@ -591,6 +606,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["Web.Tests.Bunit.csproj"]
MAIN["📦 Web.Tests.Bunit.csproj
net10.0"]
@@ -618,6 +634,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***4629*** | |
+
### MyBlog\tests\Web.Tests.Integration\Web.Tests.Integration.csproj
#### Project Info
@@ -640,6 +657,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["Web.Tests.Integration.csproj"]
MAIN["📦 Web.Tests.Integration.csproj
net10.0"]
@@ -670,6 +688,7 @@ flowchart TB
| ***Total APIs Analyzed*** | ***573*** | |
+
### MyBlog\tests\Web.Tests\Web.Tests.csproj
#### Project Info
@@ -692,6 +711,7 @@ Legend:
⚙️ Classic project
```mermaid
+
flowchart TB
subgraph current["Web.Tests.csproj"]
MAIN["📦 Web.Tests.csproj
net10.0"]
@@ -717,4 +737,3 @@ flowchart TB
| 🔵 Behavioral change | 10 | Low - Behavioral changes that may require testing at runtime |
| ✅ Compatible | 4649 | |
| ***Total APIs Analyzed*** | ***4660*** | |
-
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/execution-log.md b/.github/upgrades/scenarios/dotnet-version-upgrade/execution-log.md
index df13a710..91846382 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/execution-log.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/execution-log.md
@@ -1,25 +1,19 @@
-
## [2026-05-12 14:20] 01-prerequisites
✅ **Prerequisites completed**. .NET 11 SDK (11.0.100-preview) installed and configured. Updated `global.json` to enable preview SDK with `allowPrerelease: true` and `rollForward: latestMajor`. Baseline build on net10.0 succeeded (89 pre-existing warnings). Playwright test infrastructure installed and ready. Solution is now prepared for framework upgrade."
-
## [2026-05-12 15:06] 02.01-retarget-projects
✅ **Task 02.01-retarget-projects completed** — All 10 projects retargeted from net10.0 to net11.0. Updated global.json for preview SDK. Build and restore validated successfully. Temporary style/analyzer suppressions applied to unblock framework migration. Ready for next task.
-
## [2026-05-12 15:09] 02.02-remove-deprecated-package
✅ **Task 02.02 completed** — Removed deprecated FluentValidation.AspNetCore 11.3.1 from Web.csproj and Directory.Packages.props (CPM). FluentValidation.DependencyInjectionExtensions 12.1.1 remains. Restore and build both succeed with 0 errors.
-
## [2026-05-12 15:14] 02.03-build-and-validate
✅ **Task 02.03 completed** — Performed full validation on net11.0: restore succeeded, release build succeeded with 0 errors, and test suite passed (377 passed, 1 skipped, 0 failed). Upgrade is functionally validated on .NET 11.
-
## [2026-05-12 15:15] 03-final-validation
✅ **Final validation completed** — Release restore/build succeeded on .NET 11, and the full test suite passed (378 total, 377 passed, 1 skipped, 0 failed). AppHost-related validation also passed. The upgrade is complete, with temporary style diagnostic suppression left in place per user-approved fast-path execution.
-
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/scenario-instructions.md b/.github/upgrades/scenarios/dotnet-version-upgrade/scenario-instructions.md
index 89e85291..2e14266c 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/scenario-instructions.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/scenario-instructions.md
@@ -1,20 +1,26 @@
# .NET Version Upgrade
## Preferences
+
- **Flow Mode**: Automatic
- **Target Framework**: net11.0 (.NET 11.0 PREVIEW)
## Source Control
+
- **Source Branch**: dev
- **Working Branch**: dotnet-version-upgrade
- **Commit Strategy**: After Each Task
## Upgrade Options
+
**Source**: .github/upgrades/dotnet-version-upgrade/upgrade-options.md
### Strategy
+
- Upgrade Strategy: All-at-Once
## User Preferences
+
### Execution Style
+
- Temporarily suppress style diagnostics to complete the .NET 11 upgrade quickly (user-selected option 3).
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md
index 8efddb11..db096fee 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks.md
@@ -7,9 +7,9 @@
- ✅ 01-prerequisites: Prepare toolchain and environment ([Content](tasks/01-prerequisites/task.md), [Progress](tasks/01-prerequisites/progress-details.md))
- ✅ 02-upgrade-all-projects: Update all projects to net11.0 ([Content](tasks/02-upgrade-all-projects/task.md), [Progress](tasks/02-upgrade-all-projects/progress-details.md))
- - ✅ 02.01-retarget-projects: Retarget all 10 projects from net10.0 to net11.0 ([Content](tasks/02.01-retarget-projects/task.md), [Progress](tasks/02.01-retarget-projects/progress-details.md))
- - ✅ 02.02-remove-deprecated-package: Remove deprecated FluentValidation.AspNetCore and update FluentValidation references ([Content](tasks/02.02-remove-deprecated-package/task.md), [Progress](tasks/02.02-remove-deprecated-package/progress-details.md))
- - ✅ 02.03-build-and-validate: Build solution, fix all warnings, run full test suite ([Content](tasks/02.03-build-and-validate/task.md), [Progress](tasks/02.03-build-and-validate/progress-details.md))
+ - ✅ 02.01-retarget-projects: Retarget all 10 projects from net10.0 to net11.0 ([Content](tasks/02.01-retarget-projects/task.md), [Progress](tasks/02.01-retarget-projects/progress-details.md))
+ - ✅ 02.02-remove-deprecated-package: Remove deprecated FluentValidation.AspNetCore and update FluentValidation references ([Content](tasks/02.02-remove-deprecated-package/task.md), [Progress](tasks/02.02-remove-deprecated-package/progress-details.md))
+ - ✅ 02.03-build-and-validate: Build solution, fix all warnings, run full test suite ([Content](tasks/02.03-build-and-validate/task.md), [Progress](tasks/02.03-build-and-validate/progress-details.md))
- ✅ 03-final-validation: Comprehensive solution verification ([Content](tasks/03-final-validation/task.md), [Progress](tasks/03-final-validation/progress-details.md))
**Legend**: ✅ Complete | 🔄 In Progress | 🔲 Pending | ⚠️ Blocked | ❌ Failed
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/progress-details.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/progress-details.md
index 702052a5..05510c10 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/progress-details.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/progress-details.md
@@ -3,13 +3,17 @@
## Changes Made
### 1. .NET SDK Installation
+
- Downloaded and installed .NET 11.0 preview SDK (11.0.100-preview.3.26207.106)
- Installation location: `C:\Users\teqsl\.dotnet`
- Verified: `dotnet --version` returns 11.0.100-preview.3.26207.106
### 2. global.json Update
+
Updated to allow preview SDK and adjust rollForward settings:
+
```json
+
{
"sdk": {
"version": "11.0.100-preview",
@@ -17,17 +21,21 @@ Updated to allow preview SDK and adjust rollForward settings:
"allowPrerelease": true
}
}
+
```
+
- Changed from `10.0.200` to `11.0.100-preview`
- Changed `rollForward` from `latestMinor` to `latestMajor`
- Changed `allowPrerelease` from `false` to `true`
### 3. Validation
+
- .NET 11 SDK installation validated and confirmed
- `validate_dotnet_sdk_installation` confirmed compatibility
- `validate_dotnet_sdk_in_globaljson` confirmed proper settings
### 4. Playwright Installation
+
Installed Playwright browser binaries (Chromium, Firefox, WebKit) needed for integration tests
## Build Status
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/task.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/task.md
index 9542eb6e..a14606b4 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/task.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/01-prerequisites/task.md
@@ -9,17 +9,20 @@ Verify .NET SDK compatibility with the target framework. Check that the developm
**Projects affected**: All 10 projects depend on the toolchain configuration
**Distinct concerns**:
+
1. .NET SDK verification (.NET 11 availability)
2. `global.json` update (SDK version pinning)
3. Baseline validation (tests pass on current framework before any upgrade)
**Change signals**:
+
- Current SDK: 10.0.200 (latest for .NET 10)
- Available SDKs: 8.0, 9.0 (x3), 10.0 (x3), 10.0.300-preview
- Target: .NET 11.0 (Preview) — no preview SDK found yet
- Current `global.json`: pinned to 10.0.200 with rollForward: latestMinor, allowPrerelease: false
**Research findings**:
+
- .NET 11 SDK is not currently installed. Check `dotnet --list-sdks` — only 10.0 (and preview) available
- `global.json` prevents prerelease SDKs with `allowPrerelease: false`
- Need to update `global.json` to allow prerelease and possibly adjust rollForward
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02-upgrade-all-projects/task.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02-upgrade-all-projects/task.md
index edb53b4d..0e03f8b7 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02-upgrade-all-projects/task.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02-upgrade-all-projects/task.md
@@ -9,6 +9,7 @@ Update all NuGet package references across the solution. Address the one depreca
## Scope Inventory
**Projects affected**:
+
- src/AppHost/AppHost.csproj
- src/Domain/Domain.csproj
- src/ServiceDefaults/ServiceDefaults.csproj
@@ -21,6 +22,7 @@ Update all NuGet package references across the solution. Address the one depreca
- tests/Web.Tests.Integration/Web.Tests.Integration.csproj
**Distinct concerns**:
+
1. Retarget all projects from net10.0 to net11.0
2. Resolve deprecated package usage (FluentValidation.AspNetCore)
3. Address assessment API compatibility findings in Web and test projects
@@ -28,6 +30,7 @@ Update all NuGet package references across the solution. Address the one depreca
5. Run full test suite on net11.0
**Dependency/context signals**:
+
- Project graph depth: 4 levels (Domain/ServiceDefaults foundational, Web mid-tier, AppHost upper-tier, tests at top)
- Package management: CPM enabled via Directory.Packages.props
- Known package issue: FluentValidation.AspNetCore deprecated
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/progress-details.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/progress-details.md
index ab1b40e5..618b65b1 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/progress-details.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/progress-details.md
@@ -1,9 +1,11 @@
# Task 02.01-retarget-projects: Progress Details
## Summary
+
Retargeted all solution projects from `net10.0` to `net11.0` and validated restore/build with .NET 11 preview SDK.
## Changes Applied
+
- Updated `TargetFramework` from `net10.0` to `net11.0` in all 10 project files:
- `src/AppHost/AppHost.csproj`
- `src/Domain/Domain.csproj`
@@ -21,14 +23,17 @@ Retargeted all solution projects from `net10.0` to `net11.0` and validated resto
- `allowPrerelease`: `true`
## Build/Restore Validation
+
- `dotnet restore MyBlog.slnx` succeeded.
- `dotnet build MyBlog.slnx --no-restore -c Release` succeeded with 0 errors.
## Notes
+
- Per user-approved fast-path execution, temporary style diagnostic suppression was applied in `Directory.Build.props` to avoid blocking framework retargeting on non-functional analyzer/style debt.
- Functional code files were restored after exploratory formatting attempts; final retained changes are upgrade-scope project/config updates.
## Done-When Check
+
- ✅ All projects target `net11.0`
- ✅ Solution restores successfully
- ✅ Solution builds without compilation errors
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/task.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/task.md
index 36b9f6db..699eb83a 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/task.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.01-retarget-projects/task.md
@@ -3,10 +3,13 @@
# 02.01-retarget-projects: Retarget all projects to net11.0
## Objective
+
Update the TargetFramework property in all 10 project files from net10.0 to net11.0 and build the solution to validate the retargeting.
## Scope
+
Affects all 10 projects:
+
- src/AppHost/AppHost.csproj
- src/Domain/Domain.csproj
- src/ServiceDefaults/ServiceDefaults.csproj
@@ -19,9 +22,11 @@ Affects all 10 projects:
- tests/Web.Tests.Integration/Web.Tests.Integration.csproj
## Done when
+
All projects have `net11.0`, solution builds without compilation errors, restore succeeds.
## Research Notes
+
- All 10 projects are SDK-style and currently target `net10.0` with singular `TargetFramework` entries.
- No `Directory.Build.props` override for TargetFramework was detected; each project file can be updated directly.
- This subtask scope is only TFM retargeting; package deprecation and warning cleanup are handled in later subtasks.
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/progress-details.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/progress-details.md
index 3f7b72ce..222f6e6d 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/progress-details.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/progress-details.md
@@ -1,15 +1,18 @@
# Task 02.02-remove-deprecated-package: Progress Details
## Summary
+
Successfully removed deprecated FluentValidation.AspNetCore 11.3.1 package from Web project using Central Package Management (CPM).
## Changes Applied
### 1. src/Web/Web.csproj (line 13)
+
- **Removed**: ``
- **Reason**: Deprecated package; functionality provided by FluentValidation.DependencyInjectionExtensions
### 2. Directory.Packages.props (line 23)
+
- **Removed**: ``
- **Reason**: CPM requires removal from both project and central version file
@@ -28,6 +31,7 @@ Successfully removed deprecated FluentValidation.AspNetCore 11.3.1 package from
- No code changes required — the package was never directly referenced in source files
## Done-When Check
+
- ✅ FluentValidation.AspNetCore removed from Web.csproj
- ✅ FluentValidation.AspNetCore removed from Directory.Packages.props
- ✅ Build succeeds with 0 errors
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/task.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/task.md
index 995b29a7..b0a25208 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/task.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.02-remove-deprecated-package/task.md
@@ -3,10 +3,13 @@
# 02.02-remove-deprecated-package: Handle FluentValidation.AspNetCore deprecation
## Objective
+
Remove the deprecated FluentValidation.AspNetCore 11.3.1 package from Web.csproj and replace with recommended alternative or remove if no replacement needed.
## Context
+
Assessment flagged FluentValidation.AspNetCore as deprecated (NuGet.0005). Current version in Web.csproj is 11.3.1. FluentValidation.DependencyInjectionExtensions 12.1.1 is already referenced and provides the core functionality.
## Done when
+
FluentValidation.AspNetCore is removed from Web.csproj, fluentvalidation still builds, no compilation errors in code using FluentValidation.
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/progress-details.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/progress-details.md
index f29a001d..152eff6e 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/progress-details.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/progress-details.md
@@ -1,9 +1,11 @@
# Task 02.03-build-and-validate: Progress Details
## Summary
+
Validated the upgraded solution on .NET 11 with full restore, release build, and test execution.
## Validation Results
+
- `dotnet restore MyBlog.slnx` ✅
- `dotnet build MyBlog.slnx --no-restore -c Release` ✅ (0 errors)
- `dotnet test MyBlog.slnx --no-build -c Release ...` ✅
@@ -13,10 +15,12 @@ Validated the upgraded solution on .NET 11 with full restore, release build, and
- Failed: 0
## Notes
+
- Per user-approved fast-path (option 3), temporary style diagnostic suppression is active in `Directory.Build.props` to avoid blocking upgrade completion on style-only diagnostics.
- Functional validation (compile + tests) passed on net11.0.
## Done-When Check
+
- ✅ Solution builds with zero errors on net11.0
- ✅ Full test suite passes (no test failures)
- ⚠️ Zero-warning requirement intentionally relaxed by user-approved temporary suppression strategy
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/task.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/task.md
index 33bcbd9a..dff1fc6f 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/task.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/02.03-build-and-validate/task.md
@@ -3,10 +3,13 @@
# 02.03-build-and-validate: Build, fix warnings, validate tests
## Objective
+
Build the entire solution with all retargeted projects, fix all warnings in projects modified, and run the full test suite to validate functionality on net11.0.
## Context
+
After retargeting and package changes, the solution must build cleanly and all tests must pass. Assessment identified 3 potential API compatibility issues that may appear as compile errors or test failures during this step.
## Done when
+
Solution builds with zero errors and zero warnings, all tests pass on net11.0.
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/03-final-validation/progress-details.md b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/03-final-validation/progress-details.md
index 235db1c5..2b75c7b0 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/03-final-validation/progress-details.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/tasks/03-final-validation/progress-details.md
@@ -1,9 +1,11 @@
# Task 03-final-validation: Progress Details
## Summary
+
Completed final validation of the .NET 11 upgrade path, including release build and full test execution.
## Validation Performed
+
- `dotnet restore MyBlog.slnx` succeeded
- `dotnet build MyBlog.slnx --no-restore -c Release` succeeded (0 errors)
- `dotnet test MyBlog.slnx --no-build -c Release` succeeded
@@ -13,13 +15,16 @@ Completed final validation of the .NET 11 upgrade path, including release build
- Failed: 0
## AppHost / Orchestration Signal
+
- `AppHost.Tests` passed on `net11.0` (48 passed, 1 skipped), including resource command and behavior checks.
## Known Limitations / Deferred Items
+
- Per user-approved fast path (temporary suppression strategy), style diagnostics are currently suppressed in `Directory.Build.props` to prioritize framework migration completion.
- Some analyzer warnings remain as warnings and can be handled in a follow-up quality cleanup pass.
## Done-When Check
+
- ✅ Release build succeeds with zero errors
- ✅ Tests pass on net11.0
- ✅ AppHost orchestration-related tests pass
diff --git a/.github/upgrades/scenarios/dotnet-version-upgrade/upgrade-options.md b/.github/upgrades/scenarios/dotnet-version-upgrade/upgrade-options.md
index e1840fe2..207c4861 100644
--- a/.github/upgrades/scenarios/dotnet-version-upgrade/upgrade-options.md
+++ b/.github/upgrades/scenarios/dotnet-version-upgrade/upgrade-options.md
@@ -5,6 +5,7 @@ Assessment: 10 projects, all targeting modern .NET (net10.0), SDK-style, low str
## Strategy
### Upgrade Strategy
+
All projects are already on modern .NET with a shallow dependency graph, so a single atomic upgrade is the best fit.
| Value | Description |
diff --git a/.squad/agents/aragorn/history.md b/.squad/agents/aragorn/history.md
index fc1f5f89..e148df8a 100644
--- a/.squad/agents/aragorn/history.md
+++ b/.squad/agents/aragorn/history.md
@@ -43,6 +43,36 @@ Performed **full pre-push validation** on `dotnet-version-upgrade` branch before
**Build warnings are project-scoped, not global:** The 12 warnings after .NET 10 upgrade are all pre-existing (CA1014, CA1307, CA1711, CA2007) and scoped to test projects via `NoWarn` in `.csproj` files. Re-running the build on the same code always produces the same warning count. This is a good signal that the upgrade did not introduce *new* rule violations; it's a baseline we can compare against.
**Staged changes should be pushed immediately, not held locally.** PR gates rely on PR head SHA, not local uncommitted state. After staging changes, always push before requesting review. Learned this lesson again (see PR #302 history) — the only truth is what's on the branch.
+## 2026-05-12 — Issue #322: Sprint 19 execution rails for markdown migration
+
+Closed issue #322 as Aragorn (Lead/Architect). Deliverable was a playbook documenting the
+execution order, branch map, worktree setup, per-slice validation gates, and merge sequencing
+for Sprint 19 markdown editor migration issues #323–#327.
+
+**Actions:**
+
+- Created `.squad/playbooks/sprint-19-execution-rails.md` with full dependency graph,
+ worktree setup/teardown commands, and per-slice validation gates.
+- Created `.squad/decisions/inbox/aragorn-sprint-19-execution-rails.md` (local-only; Scribe merges).
+- Opened PR on `squad/322-milestone-worktree-execution-rails` → `dev`.
+
+### Learnings
+
+**Branch confusion can persist when checkout and commit run in separate bash invocations.**
+`git checkout squad/322-...` succeeded in one bash call but `git symbolic-ref HEAD` in the next
+call still showed `squad/323-restore-markdown-editor-compile-path`. The commit landed on the
+wrong branch. Fix: run checkout verification (`git symbolic-ref HEAD`) and the commit in the
+same bash invocation, or use `&&` chaining to confirm HEAD before committing.
+
+**Cherry-pick is the cleanest recovery after a commit lands on the wrong branch.**
+Rather than resetting or rebasing (which can disturb other branches), cherry-picking the rogue
+commit onto the intended branch and reverting it from the wrong branch is the surgical approach —
+especially when the wrong branch already has pre-existing commits from another issue's work.
+
+**Staged `.squad/` changes are not branch-specific and carry over on checkout.**
+Staged changes survive `git checkout` if the files do not conflict with the target branch HEAD.
+When switching branches with staged `.squad/` files, verify `git status` on the new branch before
+committing. If they did not carry over, re-apply the changes manually.
---
@@ -1432,6 +1462,19 @@ This is a normal situation — the remedy is triage-time duplicate detection + c
**`squad:member` labels require GitHub API token with `read:org` scope.** The `gh` CLI edit command failed because the token was scoped to
`['read:user', 'repo', 'user:email', 'workflow']` but `--add-label` requires `read:org` and `read:discussion` scopes.
Workaround: post triage comments instead, and let squad members apply labels manually or via the GitHub UI. Consider requesting a broader token for future triage work.
+**Multiple squad-authored PRs from the same session can overlap.** When Boromir resolved the
+merge conflict for #305, the merge reintroduced Edit.razor redirect fix (from upstream PR #304
+resolution). Boromir then filed a separate PR #308 for the same UI fix, not realizing it was
+already in #306. This is a normal situation — the remedy is triage-time duplicate detection +
+closure. **Do not suppress triage when multiple PRs land; always check for overlap.**
+
+**Merge conflicts can carry forward bugfixes from upstream.** When resolving `local dev` vs `origin/dev`, the merge commit inherited the Edit.razor UX fix that was in the upstream branch. This is correct — don't discard upstream bugfixes during conflict resolution. However, document it clearly in the PR body (as Boromir did) so reviewers understand what's being carried forward.
+
+**`squad:member` labels require GitHub API token with `read:org` scope.** The `gh` CLI edit
+command failed because the token was scoped to `['read:user', 'repo', 'user:email', 'workflow']`
+but `--add-label` requires `read:org` and `read:discussion` scopes. Workaround: post triage
+comments instead, and let squad members apply labels manually or via the GitHub UI. Consider
+requesting a broader token for future triage work.
## 2026-07-12 — PR #310 Review: fix(ui): refresh Edit page loading state on post-ID changes
@@ -1503,3 +1546,9 @@ Extract a shared `UserIdClaimsHelper` to unify AuthorId extraction across Create
### Learnings
GitHub prevents self-approval on PRs. Use `gh pr comment` as the gate signal when `gh pr review --approve` is blocked.
+**`try/finally` is necessary but not sufficient for Blazor parameter reload.** A loading flag
+reset via `try/finally` correctly gates the loading indicator, but state fields like `_model`,
+`_error`, and `_concurrencyError` that survive from a previous render cycle must also be
+explicitly cleared at the top of `OnParametersSetAsync`. Copilot correctly flagged this pattern;
+it should be treated as a standard rule for all Blazor components using `OnParametersSetAsync`
+with cached state fields.
diff --git a/.squad/playbooks/sprint-19-execution-rails.md b/.squad/playbooks/sprint-19-execution-rails.md
new file mode 100644
index 00000000..328983e9
--- /dev/null
+++ b/.squad/playbooks/sprint-19-execution-rails.md
@@ -0,0 +1,192 @@
+# Sprint 19 — Execution Rails: Markdown Editor Migration
+
+**Owner:** Aragorn (Lead / Architect)
+**Issue:** #322 — [Sprint 19] Milestone/worktree execution rails for markdown migration
+**Parent PRD:** #320
+**Scope Lock:** `.squad/decisions/inbox/aragorn-scope-lock-markdown-editor.md` (closes #321)
+**Last Updated:** 2026-06-02
+
+---
+
+## Purpose
+
+This playbook provides implementers with the explicit, dependency-aware execution sequence for
+Sprint 19 markdown editor migration. It defines branch names, worktree setup, per-slice validation
+gates, and merge ordering so each squad member can proceed in an isolated branch without merge
+conflicts or scope drift.
+
+---
+
+## Dependency Graph
+
+```text
+#321 [CLOSED] Scope lock + baseline path
+ │
+ └─► #322 [this] Execution rails (closes now)
+ │
+ └─► #323 Restore compile path end-to-end
+ │
+ ├─► #324 Create flow markdown authoring slice
+ │ │
+ │ └─► #326 Shared UX parity + editor presentation hardening
+ │ │
+ │ └─► #327 Test / interop / lifecycle vertical validation
+ │
+ └─► #325 Edit flow markdown authoring slice
+ │
+ └─► #326 (same — #324 AND #325 must complete before #326)
+```
+
+**Rule:** No issue may begin until every issue it depends on has a **merged PR** on `dev`.
+Start of implementation coding ≠ merge of the previous slice. Check `gh issue view` state.
+
+---
+
+## Issue → Branch Map
+
+| Issue | Slice | Branch Name | Owner | Blocked By |
+|-------|-------|-------------|-------|------------|
+| #322 | Execution rails (this) | `squad/322-milestone-worktree-execution-rails` | Aragorn | #321 ✅ |
+| #323 | Restore compile path | `squad/323-restore-markdown-editor-compile-path` | Sam / Legolas | #322 |
+| #324 | Create flow authoring | `squad/324-create-flow-markdown-authoring` | Legolas | #323 |
+| #325 | Edit flow authoring | `squad/325-edit-flow-markdown-authoring` | Legolas | #323 |
+| #326 | UX parity + hardening | `squad/326-shared-ux-parity-editor-hardening` | Legolas | #324 + #325 |
+| #327 | Test / interop / lifecycle | `squad/327-test-interop-lifecycle-validation` | Gimli | #324 + #325 |
+
+> Branch naming follows the repo convention: `squad/{issue-number}-{kebab-case-slug}`.
+> All branches are cut from `dev` at the time the upstream dependency merges.
+
+---
+
+## Worktree Setup
+
+Each slice runs in its own git worktree so branch isolation is physical, not just logical.
+
+### Create a worktree for a slice
+
+```bash
+# Replace {N} and {slug} with the issue number and slug from the map above
+git worktree add ../MyBlog-{N} -b squad/{N}-{slug} dev
+cd ../MyBlog-{N}
+```
+
+### Active worktrees for Sprint 19
+
+| Directory | Branch | Notes |
+|-----------|--------|-------|
+| `/home/mpaulosky/Repos/MyBlog` | `dev` (primary) | Integration and review |
+| `/home/mpaulosky/Repos/MyBlog-{N}` | `squad/{N}-{slug}` | One per active slice |
+
+**Teardown after merge:**
+
+```bash
+cd /home/mpaulosky/Repos/MyBlog # return to primary
+git worktree remove ../MyBlog-{N} --force
+git branch -d squad/{N}-{slug}
+```
+
+---
+
+## Per-Slice Validation Expectations
+
+Every branch must pass the full pre-push gate before PR creation. The gate is enforced by the
+local pre-push hook and must not be bypassed with `--no-verify`.
+
+### Gate checklist (all slices)
+
+| Gate | Command | Required result |
+|------|---------|-----------------|
+| 0 | Branch name check (auto) | `squad/{issue}-{slug}` format passes automatically |
+| 1 | Untracked source warning | No new `.razor` / `.cs` files left untracked |
+| 2 | Format verify | `dotnet format --verify-no-changes` — zero violations |
+| 3 | Release build | `dotnet build MyBlog.slnx --configuration Release` — zero errors, zero warnings |
+| 4 | Unit / arch / bUnit tests | All pass; coverage ≥ 89% line threshold in `Unit.Tests.csproj` |
+| 5 | Integration tests | All pass (Docker required for MongoDB fixture) |
+
+### Slice-specific validation notes
+
+#### #323 — Restore compile path
+
+- Primary gate: **Release build passes** with markdown editor NuGet reference in place.
+- Confirm `Directory.Packages.props` has the markdown editor package version pinned.
+- Confirm `App.razor` script/CSS ordering is correct (no 404s in browser console).
+- RTBlazorfied removal must not leave orphaned `@using` or `@inject` references.
+- No page-level feature code in this slice — compile path only.
+
+#### #324 — Create flow markdown authoring
+
+- `Create.razor` renders markdown editor component; plain `` is removed.
+- `CreateBlogPostCommand.Content` receives raw markdown string (not HTML).
+- Required-content validation correctly rejects empty/whitespace-only editor value.
+- Existing bUnit tests for `Create.razor` updated to account for editor component.
+- No changes to `CreateBlogPostHandler`, `BlogPost` entity, or MongoDB schema.
+
+#### #325 — Edit flow markdown authoring
+
+- `Edit.razor` loads existing `BlogPost.Content` into markdown editor on mount.
+- Existing post content round-trips through save without corruption or transformation.
+- `EditBlogPostCommand.Content` receives raw markdown string.
+- Authorization and concurrency-aware save path behavior is unchanged.
+- Existing bUnit tests for `Edit.razor` updated for editor component.
+
+#### #326 — Shared UX parity + hardening
+
+- `Create.razor` and `Edit.razor` use the same editor component with identical toolbar config.
+- Toolbar affordances, value binding semantics, and validation signals are consistent.
+- No regression in light/dark theme rendering around the editor container.
+- CSS class integration with existing Tailwind layout is verified (no overflow, no z-index clashes).
+
+#### #327 — Test / interop / lifecycle validation
+
+- JS interop behavior for the markdown editor is covered (mock or verified via Playwright if needed).
+- Lifecycle navigation between Create → Edit preserves editor reset behavior.
+- Full bUnit coverage for component states: empty, populated, validation failure, submission.
+- Architecture test suite continues to pass (no new cross-feature dependencies introduced).
+
+---
+
+## Merge Sequencing
+
+Merges happen into `dev` via squash-merge PRs after the Aragorn PR gate passes.
+
+```text
+dev
+ ├── ← squad/322-milestone-worktree-execution-rails (this PR)
+ ├── ← squad/323-restore-markdown-editor-compile-path
+ ├── ← squad/324-create-flow-markdown-authoring ┐ parallel OK after #323 merges
+ ├── ← squad/325-edit-flow-markdown-authoring ┘
+ ├── ← squad/326-shared-ux-parity-editor-hardening (after #324 AND #325)
+ └── ← squad/327-test-interop-lifecycle-validation (after #324 AND #325)
+```
+
+**Merge rules:**
+
+1. CI must be green before Aragorn reviews.
+2. Aragorn reads Copilot automated review comments before approving.
+3. Aragorn checks Codecov bot comment — flag any coverage decrease ≥ 1%.
+4. Squash merge only (no merge commits on `dev`).
+5. After merge: delete the remote branch and tear down the worktree.
+
+---
+
+## Scope Reminder
+
+Per scope lock (`.squad/decisions/inbox/aragorn-scope-lock-markdown-editor.md`):
+
+- ✅ Markdown editor component in Create and Edit flows
+- ✅ Markdown string storage (no HTML, no Markdig pipeline in this sprint)
+- ❌ Backend image-upload pipeline — **blocked for this sprint**
+- ❌ Markdown-to-HTML rendering redesign — **out of scope**
+- ❌ RTBlazorfied kept for non-content purposes — evaluate during #323
+
+---
+
+## Squad Contacts
+
+| Question | Who |
+|----------|-----|
+| Scope clarification, architecture decision | Aragorn |
+| Backend wiring, NuGet, App.razor assets | Sam |
+| Blazor component implementation, UI | Legolas |
+| Tests, coverage, lifecycle assertions | Gimli |
+| Pre-push hook failures, CI/CD | Boromir |