element in wwwroot/index.html.
+builder.RootComponents.Add
("#app");
+
+// HeadOutlet manages elements (title, meta tags) from Razor components.
+builder.RootComponents.Add("head::after");
+
+// Read the API base URL from configuration (wwwroot/appsettings.json).
+// This file is PUBLIC -- never put secrets here.
+var apiBaseUrl = builder.Configuration["ApiBaseUrl"]
+ ?? "https://localhost:7100";
+
+// Register ChatApiClient as a typed HttpClient.
+// AddHttpClient uses IHttpClientFactory internally, which:
+// - Manages HttpClient lifetimes properly (avoids socket exhaustion)
+// - Allows per-client configuration (base address, headers)
+// - Makes the service injectable via constructor DI
+builder.Services.AddHttpClient(client =>
+{
+ client.BaseAddress = new Uri(apiBaseUrl);
+});
+
+await builder.Build().RunAsync();
+```
+
+### API Program.cs (Server)
+```csharp
+// Program.cs -- ASP.NET Core Web API entry point
+// This is the backend server that the Blazor WASM client talks to.
+// It will eventually proxy OpenAI calls and manage JSON file storage.
+// In Phase 1, it only serves a health check endpoint.
+var builder = WebApplication.CreateBuilder(args);
+
+// AddControllers() registers MVC controller services.
+// We use Controllers (not Minimal API) for explicit structure (D-05).
+builder.Services.AddControllers();
+
+// CORS (Cross-Origin Resource Sharing) configuration.
+// The WASM client runs on a different origin (different port),
+// so the browser blocks requests unless the server explicitly allows them.
+builder.Services.AddCors(options =>
+{
+ options.AddPolicy("AllowBlazorClient", policy =>
+ {
+ // TODO: Read from configuration instead of hardcoding
+ policy.WithOrigins("https://localhost:5200")
+ .AllowAnyHeader()
+ .AllowAnyMethod();
+ });
+});
+
+var app = builder.Build();
+
+// Middleware order matters in ASP.NET Core.
+// CORS must be applied before routing and authorization.
+app.UseCors("AllowBlazorClient");
+
+app.UseAuthorization();
+
+// MapControllers() discovers all [ApiController] classes
+// and maps their [HttpGet], [HttpPost], etc. attributes to routes.
+app.MapControllers();
+
+app.Run();
+```
+
+## State of the Art
+
+| Old Approach | Current Approach | When Changed | Impact |
+|--------------|------------------|--------------|--------|
+| Hosted Blazor WASM template (Client+Server+Shared in one template) | Separate projects added to a manual solution | .NET 8 (Nov 2023) | Must create three projects manually; no `--hosted` flag |
+| `Newtonsoft.Json` for serialization | `System.Text.Json` built into .NET | .NET Core 3.0+ | No extra dependency; source generators for trim safety |
+| `HttpClient` registered directly as Singleton/Scoped | `IHttpClientFactory` via `AddHttpClient` | .NET Core 2.1+ | Proper socket management; typed clients for clean architecture |
+
+## .NET Version Decision (Claude's Discretion)
+
+**Recommendation: Target .NET 9 (`net9.0`)**
+
+Rationale:
+- CLAUDE.md explicitly specifies .NET 9 as the target
+- .NET 9.0.312 SDK is installed on this machine
+- .NET 10 SDK (10.0.201) is also available but is not yet at LTS; using it in a tutorial project risks encountering preview-stage breaking changes
+- All recommended packages (OpenAI 2.9.1, Markdig 1.1.1, MudBlazor 9.2.0) are confirmed compatible with .NET 9
+- The `blazorwasm` template with `--framework net9.0` is verified working
+
+## Validation Architecture
+
+### Test Framework
+| Property | Value |
+|----------|-------|
+| Framework | None yet (greenfield) |
+| Config file | None -- see Wave 0 |
+| Quick run command | `dotnet build ChatAgent.sln` |
+| Full suite command | `dotnet build ChatAgent.sln && dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo` |
+
+### Phase Requirements -> Test Map
+| Req ID | Behavior | Test Type | Automated Command | File Exists? |
+|--------|----------|-----------|-------------------|-------------|
+| CODE-01 | Every file has inline comments explaining Blazor concepts | manual | Manual review of all `.cs` and `.razor` files | N/A |
+| CODE-02 | Phase introduces one concept incrementally | manual | Manual review -- Phase 1 concept = "solution structure and project boundaries" | N/A |
+| (SC-1) | `dotnet run` starts both projects without errors | smoke | `dotnet build ChatAgent.sln` (build verification) | N/A -- Wave 0 |
+| (SC-2) | WASM client reaches API server (CORS working) | integration | Manual -- start both projects, verify health endpoint from client UI | N/A |
+| (SC-3) | Shared models referenced by both projects | build | `dotnet build ChatAgent.sln` (compile-time check) | N/A -- Wave 0 |
+| (SC-4) | `dotnet publish` completes with no IL trim warnings | smoke | `dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo 2>&1 \| grep -c "warning IL"` | N/A -- Wave 0 |
+| (SC-5) | Every file contains inline comments | manual | Manual review | N/A |
+
+### Sampling Rate
+- **Per task commit:** `dotnet build ChatAgent.sln`
+- **Per wave merge:** `dotnet build ChatAgent.sln && dotnet publish src/ChatAgent.Client/ChatAgent.Client.csproj -c Release --nologo`
+- **Phase gate:** Full build + publish clean + manual CORS verification
+
+### Wave 0 Gaps
+- No formal test project needed in Phase 1 -- the verification is build success + publish success + manual CORS check
+- The `dotnet build` and `dotnet publish` commands serve as the automated validation
+- CODE-01 and CODE-02 are inherently manual-review requirements
+
+## Environment Availability
+
+| Dependency | Required By | Available | Version | Fallback |
+|------------|------------|-----------|---------|----------|
+| .NET 9 SDK | All projects | Yes | 9.0.312 | -- |
+| .NET 10 SDK | Not required | Yes | 10.0.201 | -- |
+| `dotnet new blazorwasm` template | Client project | Yes | Included in SDK | -- |
+| `dotnet new webapi` template | API project | Yes | Included in SDK | -- |
+| `dotnet new classlib` template | Shared project | Yes | Included in SDK | -- |
+| HTTPS dev certificate | Local HTTPS | Unknown | -- | Use `--no-https` flag or run `dotnet dev-certs https --trust` |
+
+**Missing dependencies with no fallback:** None.
+
+**Missing dependencies with fallback:**
+- HTTPS dev certificate status is unknown -- if untrusted, can use HTTP for Phase 1 local dev or run the trust command.
+
+## Open Questions
+
+1. **Port numbers for local development**
+ - What we know: Templates assign ports in `launchSettings.json` which vary per creation
+ - What's unclear: Exact ports until projects are actually created
+ - Recommendation: After project creation, inspect both `launchSettings.json` files and align CORS config with actual client URL. Consider setting explicit predictable ports (e.g., Client: 5200, API: 7100).
+
+2. **HTTPS vs HTTP for Phase 1 local dev**
+ - What we know: HTTPS requires a trusted dev certificate
+ - What's unclear: Whether the dev cert is already trusted on this machine
+ - Recommendation: Attempt HTTPS first. If certificate issues arise, fall back to HTTP for Phase 1 (add `--no-https` and use `http://` URLs). HTTPS can be re-enabled in later phases.
+
+## Project Constraints (from CLAUDE.md)
+
+- **Tech stack**: .NET / C# / Blazor WebAssembly -- non-negotiable
+- **LLM provider**: OpenAI GPT API (not used in Phase 1, but architecture must support it)
+- **Storage**: JSON files on local disk (not used in Phase 1, but architecture must support it)
+- **Architecture**: WASM client + backend API (API key stays server-side)
+- **Code style**: Every Blazor concept introduced must have inline comments explaining what it does and why
+- **GSD Workflow**: Use GSD entry points for all file changes
+
+## Sources
+
+### Primary (HIGH confidence)
+- .NET 9 SDK verified installed: `dotnet --list-sdks` shows 9.0.312
+- `blazorwasm` template verified: `dotnet new list blazorwasm` confirms availability
+- `webapi --use-controllers` flag verified: `dotnet new webapi --help` confirms option exists
+- Template output verified: Created temporary projects to confirm `Program.cs` structure, `.csproj` contents, and default file layout
+
+### Secondary (MEDIUM confidence)
+- `.planning/research/ARCHITECTURE.md` -- pre-existing project research on WASM/API split patterns
+- `.planning/research/STACK.md` -- pre-existing stack research with NuGet-verified versions
+- `.planning/research/PITFALLS.md` -- pre-existing pitfalls research from official GitHub issues
+
+### Tertiary (LOW confidence)
+- None -- all findings verified against installed SDK and official templates
+
+## Metadata
+
+**Confidence breakdown:**
+- Standard stack: HIGH -- verified against installed SDK and templates
+- Architecture: HIGH -- three-project structure is well-documented Microsoft pattern; template output confirmed
+- Pitfalls: HIGH -- CORS ordering, port mismatch, and IL trimming are well-known ASP.NET Core issues documented in official sources
+
+**Research date:** 2026-03-27
+**Valid until:** 2026-04-27 (stable -- .NET 9 is mature, templates are not changing)