## Deferred from: code review of 2-1-municipality-to-cycle-kanban-entry-point.md (2026-05-07) - Test coverage gaps for non-happy-path lane permutations (empty-first-lane mount, multi-cycle municipality across closed cycles). Pre-existing pattern across earlier stories; address opportunistically. - Vite build large-chunk warning persists. Pre-existing; bundle-splitting work belongs in a hardening pass, not this story. - JCode normalization mismatch between profiles and cycle-job assignments. Carried forward from Story 1-10 (Epic 1 retro MEDIUM). Joins in the kanban read model can silently drop assignments whose stored JCode has whitespace variants. Address when a hardening pass touches the legacy join paths. - Quick-open uses raw `window.history.pushState` instead of the workspace router. Story spec explicitly permits a route stub until Story 2.2; finalize navigation primitive when 2.2 wires the destination route. - Audit boundary inconsistency: Story 2-1 audits in the controller; Epic 1 pattern audits at the service/read-model edge. Revisit when additional read endpoints accumulate so the boundary can be formalized once with evidence. ## Deferred from: code review of 1-11-municipality-operational-addresses.md (2026-05-06) - `State` field on `MunicipalityAddress` is a free-text string with no format or valid-value validation. Evidence: `Campaign_Tracker.Server/Models/MunicipalityAddress.cs:25`. Deferred — may be intentional if the app supports non-US addresses; add `[RegularExpression]` or enum constraint if US-only. - `MunicipalityId` on `CreateAddressAsync` is not validated to exist before insert — invalid IDs surface as `DbUpdateException` instead of a clean 400. Evidence: `Campaign_Tracker.Server/Services/MunicipalityAddressService.cs:46`. Deferred — EF FK constraint enforces integrity at the database level; UX improvement only. ## Deferred from: code review of 1-10-municipality-account-profile.md (2026-05-06) - Internal whitespace in JCode from Access not handled — `Trim()` strips leading/trailing only; JCodes with embedded spaces would cause lookup mismatches between `GetAllJurisdictionsAsync` and `GetJurisdictionAsync`. Evidence: `Campaign_Tracker.Server/LegacyData/OleDbLegacyDataAccess.cs`. Pre-existing data-quality risk; fix requires confirming Access data characteristics. - `ProfileId` uses `Guid.NewGuid().ToString("N")` (no hyphens) — latent cross-system UUID format mismatch if an external consumer returns a hyphenated UUID variant. Evidence: `Campaign_Tracker.Server/Municipalities/InMemoryMunicipalityProfileRepository.cs`. Pre-existing design choice; consistent within the codebase today. - `CreatedAt` stored on `MunicipalityProfile` but absent from API response DTO and frontend contract — profile creation timestamp inaccessible to consumers. Evidence: `MunicipalityProfileResponse` record in `MunicipalityProfileController.cs`. Not required by story spec; can be added in a future story. - Audit `Outcome` hardcoded to `"updated display name"` — will become misleading once the profile model gains additional updatable fields. Evidence: `MunicipalityProfileController.Update`. Only `DisplayName` is editable today; acceptable short-term. - `refresh()` post-create does not reload the jurisdiction list — list can grow stale if jurisdictions are added to the legacy database during the session. Evidence: `MunicipalityProfilePanel.tsx` `handleCreate`. Minor UX gap; low impact in practice. ## Deferred from: fix-strictmode-oidc-callback-race (2026-05-06) - `pendingCallbackSequence` is not scoped to a specific callback invocation — if `useOidcSession` were ever mounted twice simultaneously, the second instance would skip CSRF validation and piggyback on the first's exchange. Pre-existing architectural assumption; low risk given single-mount usage, but worth an assertion if the hook gains wider use. - `user.workspacePath` is used in `window.history.replaceState` without validating it is a relative path. Server currently returns only hard-coded relative paths, but an open-redirect risk exists if the return value ever comes from user-controlled input. ## Deferred from: code review of 1-4-keycloak-role-mapping-application-authorization.md (2026-05-06) - AuthorizationProbeController ships canned operational routes in the production controller surface. Evidence: Campaign_Tracker.Server/Controllers/AuthorizationProbeController.cs:8. Reason: deferred by user choice during review. ## Deferred from: code review of 1-7-legacy-schema-compatibility-validation-gate.md (2026-05-06) - Runtime audit log JSONL files are tracked and contain actor identities, resources, trace IDs, and timestamps. Evidence: Campaign_Tracker.Server/audit-logs/audit-2026-05-05.jsonl:1. Reason: pre-existing hygiene issue from the broader prior commit, not specific to Story 1.7 or 1.8 behavior.