Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .ai-team/agents/bishop/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,9 @@ Added `Convert-PageLifecycleMethods` (GAP-05) and `Convert-EventHandlerSignature
- GAP-05: Page_Load OnInitializedAsync, Page_Init OnInitialized, Page_PreRender OnAfterRenderAsync(bool firstRender)
- GAP-07: Standard EventArgs handlers strip both params; specialized *EventArgs handlers keep the EventArgs param, strip sender
- Updated 6 expected test files. All 21 L1 tests pass at 100% line accuracy.

### 2026-03-30: Squad CI Workflow fetch-depth: 0 Fix

**What:** Added etch-depth: 0 to .github/workflows/squad-ci.yml checkout step. Audited all other squad-*.yml workflows for the same issue (found existing fix in squad-insider-release.yml, squad-promote.yml, squad-release.yml).
**Why:** Nerdbank.GitVersioning requires full git history. ctions/checkout@v4 defaults to shallow clone ( etch-depth: 1), causing GitException in PR #114. Fix ensures CI checks pass with no performance impact.
**Outcome:** PR #114 CI unblocked. All .NET-building workflows now have consistent configuration.
60 changes: 60 additions & 0 deletions .ai-team/agents/psylocke/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,63 @@

Team update (2026-03-06): WebFormsPageBase is the canonical base class for all migrated pages (not ComponentBase). All agents must use WebFormsPageBase decided by Jeffrey T. Fritz
Team update (2026-03-06): LoginView is a native BWFC component do NOT convert to AuthorizeView. Strip asp: prefix only decided by Jeffrey T. Fritz

### 2026-03-30: Phase 4 Migration Skills β€” L1 Frozen, L2 Skills Created

**Strategic decision:** L1 PowerShell script (`bwfc-migrate.ps1`) is **frozen at Phase 3**. It handles ~70% of migration work (deterministic transforms). All remaining work shifts to **Layer 2 (L2) Copilot skills** for contextual, AI-guided transforms.

**Rationale:**
- Deterministic regex/AST transforms have reached their practical limit (~70% coverage)
- Remaining gaps require contextual reasoning: architecture decisions, cross-file understanding, domain knowledge
- L1 can *detect* patterns but cannot reliably *convert* them without risking incorrect migrations
- Skills provide decision trees, before/after examples, and "What Developers Must Do Manually" guidance

**Skills created:**
- `bwfc-session-state/SKILL.md` (low confidence) β€” Application["key"] β†’ singleton/scoped services, Cache["key"] β†’ IMemoryCache, HttpContext.Current β†’ IHttpContextAccessor. Covers items #13, #14, #15, #16 from migration-shim-analysis.
- `bwfc-middleware-migration/SKILL.md` (low confidence) β€” HttpModule β†’ middleware, Global.asax events β†’ Program.cs (Application_Start, Session_Start, Application_Error). Covers items #22, #23, #24.
- `bwfc-usercontrol-migration/SKILL.md` (low confidence) β€” .ascx β†’ component with [Parameter], FindControl β†’ @ref patterns, parent/child communication, event delegation. Covers items #30, #31, #8.

**Skills enhanced:**
- `bwfc-identity-migration/SKILL.md` (v2.0.0, low β†’ low confidence) β€” Added comprehensive FormsAuthentication, Membership provider, and Roles provider migration patterns. Includes:
- FormsAuthentication.SetAuthCookie β†’ HttpContext.SignInAsync in minimal API endpoints
- Membership.CreateUser β†’ UserManager<T>.CreateAsync with password hash compatibility notes
- Roles.IsUserInRole β†’ UserManager<T>.IsInRoleAsync + policy-based authorization
- Database schema migration table (Membership β†’ Identity)
- Migration cheat sheet for detecting auth system in Web Forms projects
- Covers items #25, #26, #27 from migration-shim-analysis.

**Updated documentation:**
- `bwfc-migration/CODE-TRANSFORMS.md` β€” Added "Phase 4: Skills-Based Transforms" section explaining:
- Why L1 is frozen (deterministic vs contextual)
- L1 vs L2 decision table
- Three-layer migration strategy (L1 automated, L2 AI-guided, L3 developer judgment)
- Links to each Phase 4 skill

**Key patterns identified:**
- **Application state decisions:** L1 can detect `Application["key"]`, but only developers can decide if data is global (singleton) or per-user (scoped)
- **Cache lifetime decisions:** L1 can detect `Cache["key"]`, but only developers know if data should use IMemoryCache or IDistributedCache
- **HttpModule event mapping:** L1 can detect IHttpModule classes, but only developers understand the business logic to map correctly to middleware
- **FindControl patterns:** L1 can detect FindControl() calls, but understanding component tree structure requires human reasoning
- **Authentication system detection:** Projects may use Identity (OWIN), Membership, or FormsAuthentication β€” each requires different migration paths

**Confidence levels:**
- All new skills marked as "low confidence" β€” these are first-draft guides based on Forge's analysis
- Skills will iterate based on real-world migration feedback
- "What Developers Must Do Manually" sections explicitly document non-automatable tasks

**Team decision recorded:** L1 PowerShell frozen at Phase 3. Phase 4 = skills-based L2 transforms only.

**Skills created:**
- wfc-session-state/SKILL.md Application[], Cache[], HttpContext.Current state migration decisions (singleton vs scoped, IMemoryCache vs IDistributedCache)
- wfc-middleware-migration/SKILL.md HttpModule, Global.asax middleware conversion (event middleware position mapping, pipeline order)
- wfc-usercontrol-migration/SKILL.md .ascx, FindControl, [Parameter] component conversion (public property vs internal state, @ref timing)
- wfc-identity-migration/SKILL.md (v2) Added FormsAuthentication, Membership, Roles sections (auth system detection, password hash compatibility)

**Documentation updated:**
- migration-toolkit/skills/bwfc-migration/CODE-TRANSFORMS.md Added "Phase 4: Skills-Based Transforms" section
- .ai-team/agents/psylocke/history.md Recorded Phase 4 learnings

**Strategic outcome:** Three-layer migration model formalized and locked in:
1. L1 (PowerShell) 70% deterministic automation **FROZEN at Phase 3**
2. L2 (Skills) 25% contextual AI-guided transforms **Phase 4 active**
3. L3 (Developer) 5% architectural decisions **always requires human review**
19 changes: 18 additions & 1 deletion .ai-team/decisions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ο»Ώ# Decisions
# Decisions

> Shared team decisions. All agents read this. Only Scribe writes here (by merging from inbox).

Expand Down Expand Up @@ -7658,3 +7658,20 @@ $content = $content -replace '\s*:\s*(?:System\.Web\.UI\.)?(?:Page|UserControl|M
**Why:** User directive from Jeff + Forge's S5 recommendation. This is the single most common code-behind edit (33 files in WingtipToys). Even a partial rename saves significant time.
**Risk:** Method body may contain `sender` or `e` references that become invalid. Mitigate by flagging a TODO if those identifiers appear in the method body.
**Assign to:** Bishop

### 2026-03-30: Add fetch-depth: 0 to Squad CI Workflow

**By:** Bishop (Migration Tooling Dev)
**What:** Added etch-depth: 0 to .github/workflows/squad-ci.yml checkout step to fetch full git history. Audited all other squad-*.yml workflows: squad-insider-release.yml, squad-promote.yml, and squad-release.yml already have fetch-depth: 0. Other workflows (docs, preview, heartbeat, issue-assign, label-enforce, triage) do not build .NET code and do not require it.
**Why:** Nerdbank.GitVersioning (NBGV) requires full git history to calculate version heights by walking commit graph. ctions/checkout@v4 defaults to etch-depth: 1 (shallow clone), causing GitException. The fix is minimal, non-breaking, and ensures PR #114 CI checks pass.

### 2026-03-30: Phase 4 Migration Skills L1 PowerShell Frozen (consolidated)

**By:** Psylocke (Skills Engineer), per charter from Jeffrey T. Fritz
**What:** L1 PowerShell script (wfc-migrate.ps1) is FROZEN at Phase 3. Remaining ~30% of migration work becomes Layer 2 (L2) Copilot skills: AI-guided transforms with decision trees, before/after examples, and explicit "What Developers Must Do Manually" sections. Created 4 Phase 4 skills: wfc-session-state (Application[], Cache[], HttpContext.Current), wfc-middleware-migration (HttpModule, Global.asax), wfc-usercontrol-migration (.ascx, FindControl, [Parameter]), enhanced wfc-identity-migration v2 (FormsAuth, Membership, Roles). Three-layer migration model: L1 (automated, ~70%), L2 (AI-guided, ~25%), L3 (human, ~5%).
**Why:** L1 has reached deterministic limit at Phase 3. Remaining gaps require architecture decisions (Is Application["key"] global or per-user? IMemoryCache or IDistributedCache?), cross-file reasoning (FindControl requires understanding component trees), and domain knowledge (Membership password hashes, Global.asax event flow). Skills provide better guidance than silent script failures. Skills iterate faster than PowerShell (markdown vs code). Prevents L1 from becoming unmaintainable catch-all.
### 2026-03-30: Add fetch-depth: 0 to Squad CI Workflow

**By:** Bishop (Migration Tooling Dev)
**What:** Added etch-depth: 0 to .github/workflows/squad-ci.yml checkout step to fetch full git history. Audited all other squad-*.yml workflows: squad-insider-release.yml, squad-promote.yml, and squad-release.yml already have fetch-depth: 0. Other workflows (docs, preview, heartbeat, issue-assign, label-enforce, triage) do not build .NET code and do not require it.
**Why:** Nerdbank.GitVersioning (NBGV) requires full git history to calculate version heights by walking commit graph. ctions/checkout@v4 defaults to etch-depth: 1 (shallow clone), causing GitException. The fix is minimal, non-breaking, and ensures PR #114 CI checks pass.
48 changes: 48 additions & 0 deletions .ai-team/decisions/inbox/bishop-ci-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Decision: Add fetch-depth: 0 to Squad CI Workflow

**Date:** 2025-01-26
**Decision Maker:** Bishop (Migration Tooling Dev)
**Context:** PR #114 - Squad CI workflow failing with NBGV errors

## Problem

The `squad-ci.yml` GitHub Actions workflow was failing with:
```
Nerdbank.GitVersioning.GitException: Shallow clone lacks the object
```

This occurred because `actions/checkout@v4` defaults to `fetch-depth: 1` (shallow clone), which only fetches the most recent commit. Nerdbank.GitVersioning (NBGV) requires the full git history to calculate version heights by walking the commit graph.

## Decision

Added `fetch-depth: 0` to the checkout step in `.github/workflows/squad-ci.yml` to fetch the full git history:

```yaml
- uses: actions/checkout@v4
with:
fetch-depth: 0
```

## Audit of Other Squad Workflows

Checked all squad-*.yml workflows for the same issue:

- βœ… **squad-insider-release.yml** - Already has `fetch-depth: 0` (builds .NET)
- βœ… **squad-promote.yml** - Already has `fetch-depth: 0` on both checkouts (manages branches)
- βœ… **squad-release.yml** - Already has `fetch-depth: 0` (builds .NET)
- βšͺ **squad-docs.yml** - N/A (doesn't build .NET, just echoes placeholder)
- βšͺ **squad-preview.yml** - N/A (doesn't build .NET yet, just echoes placeholder)
- βšͺ **squad-heartbeat.yml** - N/A (only runs Node scripts for triage)
- βšͺ **squad-issue-assign.yml** - N/A (only assigns issues via GitHub API)
- βšͺ **squad-label-enforce.yml** - N/A (only enforces label rules)
- βšͺ **squad-triage.yml** - N/A (only triages issues via GitHub API)

## Impact

- PR #114 CI checks should now pass
- All .NET-building workflows now have consistent git history fetching
- No performance impact (CI already needs full history for NBGV)

## Follow-up

None required. All workflows that build .NET code and trigger NBGV already have the correct configuration.
33 changes: 33 additions & 0 deletions .ai-team/decisions/inbox/bishop-phase2-transforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Bishop Phase 2: GAP-05 + GAP-07 Code-Behind Transforms

**Date:** 2025-07-24
**Author:** Bishop (Migration Tooling Dev)
**Status:** Implemented

## Decisions Made

### D1: GAP-07 Event Handler β€” Type-name matching over inheritance check
**Decision:** Determine whether to strip both params or keep specialized EventArgs by checking if the type name is *exactly* `EventArgs` (strip both) vs. ends with `EventArgs` but is longer (keep specialized).
**Rationale:** PowerShell regex can't inspect the C# type hierarchy. String matching on `\w*EventArgs` is sufficient because all Web Forms EventArgs subtypes follow the naming convention `*EventArgs`. This avoids false positives on non-EventArgs types like `string` or `int`.
**Risk:** If a custom EventArgs subclass is named exactly `EventArgs` (impossible per C# rules) it would be incorrectly stripped. Extremely low risk.

### D2: GAP-05 Lifecycle β€” `await base.OnInitializedAsync()` injection
**Decision:** Inject `await base.OnInitializedAsync();` at the start of the converted `OnInitializedAsync` body.
**Rationale:** Blazor requires calling the base lifecycle method. Missing this call is a common source of bugs when components use `WebFormsPageBase` which has initialization logic in the base.

### D3: GAP-05 PreRender β€” `if (firstRender)` guard wrapping
**Decision:** Wrap the entire `Page_PreRender` body in `if (firstRender) { ... }` when converting to `OnAfterRenderAsync`.
**Rationale:** `Page_PreRender` runs once before the first render. `OnAfterRenderAsync` runs after *every* render. The `firstRender` guard preserves the original single-execution semantics.

### D4: Transform ordering β€” Lifecycle before Event Handlers
**Decision:** Run GAP-05 (lifecycle) before GAP-07 (event handlers) in the pipeline.
**Rationale:** Lifecycle conversion changes `Page_Load(object sender, EventArgs e)` to `OnInitializedAsync()`. If event handler conversion ran first, it would strip the lifecycle method's params but not rename it. Running lifecycle first ensures the method name is changed, and the params no longer match the event handler regex.

### D5: Test expected files updated in-place
**Decision:** Updated 6 existing expected test files (TC13–TC16, TC18, TC19) to reflect the new transforms rather than excluding lifecycle/event handler test assertions.
**Rationale:** The L1 pipeline is cumulative β€” all transforms run on every code-behind file. Expected outputs must reflect the full transform chain. Selective exclusion would be fragile and mask regressions.

## Validation
- Script parses cleanly (0 errors)
- All 21 L1 tests pass at 100% line accuracy
- TC19 (lifecycle), TC20 (standard handlers), TC21 (specialized handlers) are dedicated test cases
49 changes: 49 additions & 0 deletions .ai-team/decisions/inbox/colossus-l1-integration-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# L1 Migration Script Test Framework Extension

**Date:** 2026-03-17
**Author:** Colossus (Integration Test Engineer)
**Status:** Implemented

## Context

The L1 migration script (`migration-toolkit/scripts/bwfc-migrate.ps1`) was enhanced with 6 new capabilities in Phase 1. The test framework at `migration-toolkit/tests/` needed expansion to provide regression coverage for these enhancements.

## Decision

Extended the L1 test suite from 15 to 18 test cases by adding:

1. **TC16-IsPostBackGuard** β€” Tests GAP-06: IsPostBack guard unwrapping
2. **TC17-BindExpression** β€” Tests GAP-13: Bind() β†’ @bind-Value transform
3. **TC18-UrlCleanup** β€” Tests GAP-20: .aspx URL cleanup in Response.Redirect calls

## Test Case Design Pattern

Each test case consists of:
- **Input:** `TC##-Name.aspx` (markup) + optional `TC##-Name.aspx.cs` (code-behind)
- **Expected:** `TC##-Name.razor` (expected markup output) + optional `TC##-Name.razor.cs` (expected code-behind output)

The test runner (`Run-L1Tests.ps1`) discovers test cases by scanning `inputs/` for `.aspx` files and comparing actual script output to expected output using normalized line-by-line comparison.

## Implementation Notes

- Expected files must match **actual script output** exactly, including:
- Whitespace/indentation preserved from AST transformations
- Attributes added by script (e.g., `ItemType="object"`)
- Standard TODO comment headers
- Base class removal (`: System.Web.UI.Page` stripped)
- URL cleanup only transforms `Response.Redirect()` arguments, not arbitrary string literals
- Test suite now at 78% pass rate (14/18), 98.2% line accuracy

## Rationale

These test cases provide:
1. Regression protection for Phase 1 enhancements
2. Documentation of expected script behavior through executable examples
3. Foundation for future enhancement testing

## References

- Migration script: `migration-toolkit/scripts/bwfc-migrate.ps1`
- Test runner: `migration-toolkit/tests/Run-L1Tests.ps1`
- Test inputs: `migration-toolkit/tests/inputs/`
- Expected outputs: `migration-toolkit/tests/expected/`
22 changes: 22 additions & 0 deletions .ai-team/decisions/inbox/colossus-playwright-phase2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Decision: Phase 2 Playwright Test Strategy

**Author:** Colossus
**Date:** 2026-07-24
**Status:** Implemented

## Context

Phase 2 added SessionShim (GAP-04), Page Lifecycle Transforms (GAP-05), and Event Handler Signatures (GAP-07). GAP-05 and GAP-07 are script transforms with no dedicated UI β€” they are covered by L1 unit tests. GAP-04 has a live sample page at `/migration/session`.

## Decision

- **Test GAP-04 (SessionShim) with 5 Playwright tests** covering set/get, count, clear, typed counter, and cross-navigation persistence.
- **Add 1 regression test for the Phase 1 ConfigurationManager page** to prevent regressions.
- **Skip browser tests for GAP-05 and GAP-07** since they are script-level transforms with no direct UI surface; L1 tests provide sufficient coverage.
- **Use `data-audit-control` attribute selectors** (already present on the sample page) for robust element targeting that won't break with CSS changes.
- **Use `DOMContentLoaded` wait strategy** (not `NetworkIdle`) for interactive Blazor Server pages per established patterns.

## Files Created

- `samples/AfterBlazorServerSide.Tests/Migration/SessionDemoTests.cs` (5 tests)
- `samples/AfterBlazorServerSide.Tests/Migration/ConfigurationManagerTests.cs` (1 test)
28 changes: 28 additions & 0 deletions .ai-team/decisions/inbox/cyclops-session-shim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Decision: SessionShim Design (GAP-04)

**Date:** 2026-07-28
**By:** Cyclops (Component Dev)
**Requested by:** Jeffrey T. Fritz

## What

Implemented `SessionShim` as a scoped service that provides `Session["key"]` dictionary-style access for migrated Web Forms code. Registered in DI via `AddBlazorWebFormsComponents()`. Exposed as `protected SessionShim Session` on `WebFormsPageBase`.

## Design Choices

1. **System.Text.Json** for serialization β€” no Newtonsoft dependency, matches project zero-external-deps policy.
2. **Graceful fallback** to `ConcurrentDictionary<string, object?>` when `ISession` is unavailable (interactive Blazor Server mode). No exceptions thrown.
3. **One-time log warning** via `ILogger<SessionShim>` on first fallback β€” gives visibility without spam.
4. **`IHttpContextAccessor` as optional** constructor parameter β€” prevents DI failures in test environments.
5. **`AddDistributedMemoryCache()` + `AddSession()`** added to DI registration β€” required by ASP.NET Core session middleware. Safe to call multiple times (idempotent).
6. **`TryGetSession` wraps access in try/catch** for `InvalidOperationException` β€” covers the case where session middleware is not in the pipeline.

## Why

Web Forms apps use `Session["key"]` pervasively for shopping carts, wizard state, user preferences. This shim lets migrated code compile and run with only the `asp:` prefix removal. The fallback mode ensures Blazor Server interactive circuits work correctly (session state is per-circuit anyway).

## Impact

- `WebFormsPageBase.Session` is now available on all migrated pages
- `ServiceCollectionExtensions.AddBlazorWebFormsComponents()` now registers session infrastructure
- Build verified clean on net8.0, net9.0, net10.0
Loading
Loading