Service-layer integration hand-off

Superseded. Historical. PR 2543 completed this integration into imp/blazor-hybrid on 2026-09-23; the integration branch is now dev. The runbook below is not to be re-run.

Runbook for landing the service-layer decoupling chain in imp/blazor-hybrid-service-layer-decoupling, reconciling it with imp/blazor-hybrid, and running device acceptance once, on the tree that will ship. Written 2026-09-22 after the second-pass review of PR 2527 (ledger rows R01–R11).

State at hand-off

Item Value
Integration branch tip dca3123d — the base of PR 2505; nothing has merged yet
Active PRs into it 2505, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2527 — all "merge succeeded", no reviewers, no votes. PR 2534 (AB#2266 search-sync fix) was completed into PR 2527's branch on 2026-09-22 and rides with it.
Branch policies on the integration branch none; PRs can be completed without approval
Branch policies on imp/blazor-hybrid one required approver
Chain shape strictly linear: every phase tip is an ancestor of PR 2527's tip ce46a36a; each later PR's source branch contains the earlier ones
Only validated state PR 2527's code tip be3c7a10 (validation record), plus PR 2534's af15a0bc on hook evidence only (Debug 2,905); phases 0–7 alone carry the 118 findings that PR 2527 fixes
Drift in imp/blazor-hybrid 19 commits past the chain's merge-base 5152a5c4, chiefly PR 2521 (Presentation reorg: Pages/ and Adapters/ moved into feature subfolders), PR 2524, PR 2525
Reconciliation, pre-resolved branch chore/AB2081-service-layer-reconcile-01, tip d8bbed76: merge 55d37173 = 5e34905f + imp/blazor-hybrid@725304b3, then the PR 2534 merge (ce46a36a) folded in

Why merge in order, test once

Steps

1. Complete the nine PRs, in order

2505 → 2509 → 2510 → 2511 → 2512 → 2513 → 2514 → 2515 → 2527

2. Merge the reconciliation branch

After step 1 the integration branch's tree equals ce46a36a. Merge chore/AB2081-service-layer-reconcile-01 (tip d8bbed76) into it; it is a clean merge because d8bbed76 already contains ce46a36a. The resolutions it carries:

File Resolution
TopNav.razor.cs, AlpaIHomePage.razor.cs, JumpseatAirlinePolicyPageViewModel.cs using-block conflicts; both sides kept
ALPAMobile/Services/Authentication.cs app side's only change was a namespace rename inside the legacy logout body the service layer removed (behaviour lives in FavoritesLogoutParticipant / AuthSessionEffects); service-layer adapter kept
UnitTest/FavoritesViewModelTests.cs StubAuthentication keeps the FakeAuthentication base; cref takes the reorg's namespace
xaml-blazor-coverage-map.html timestamp-only conflict; restamped Updated 2026-09-22 11:09 ET
AuthSessionEffects.cs, LogoutParticipants.cs, HeadServiceCollectionExtensions.cs FavoriteToggleContext → ALPADocs.Components.Favorites (semantic conflict git did not flag)
UnitTest/ApiEndpointOptionsTests.cs SettingsPage → ALPADocs.Components.Pages.Profile (same)
Pages/Search/SearchPage.razor (PR 2534) git followed the reorg's rename; the IsOffline wording landed in the moved file, no stray copy at the old path

If imp/blazor-hybrid has moved again by then, repeat the merge on that branch first and expect the same class of conflict (namespace moves) rather than logic conflicts.

3. Validate the reconciled tip

Run the matrix from the validation record § Reproduction commands (Debug, Release, DocsTests, ios-debug, android-debug, ios-release, android-release, nav check, gateway catalog) and record revision, counts and TRX hashes there. The reconciliation branch's own run is recorded below.

4. Device acceptance, once

Seed preview follow-up: bea087e6 reduces the signed-in fallback to Home, Jumpseat, KCM and member MEC with the ALPA glyph. Debug 2,979 / Release 2,963 passed; the four-item state was verified at 393/440 points. Separate synthetic preview SeedMenu28 remains open; the live UAL review session is preserved. See the latest validation section.

Current correction (2026-09-23): d30a8d90 / 342d355e render local logged-out Home before live theming and restart reconciliation after final logout cleanup. Six new regressions passed; the final matrix is Debug 2,985 / Release 2,969 / Docs 4, four builds with zero errors, current navigation and 75 routes / 0 gaps. Controlled iOS Home timings were 54–74 ms despite three-second site/theme/401 replies; fresh themes applied afterward and late GLOBAL responses did not overwrite DAL. Live UAL/DAL Home was 24 ms, anonymous tabs 29/33 ms, with no empty bar and API-matched menus. The new live DAL review simulator remains open. This is focused iOS verification of the correction; earlier full walkthroughs retain their recorded revisions and were not all repeated. Keep PR 2543 auto-complete disabled pending human review. See the latest validation record for exact SHAs, evidence hashes, test-driver corrections and limitations.

On the reconciled tip only. Requirements are below; current results and remaining gates are recorded at the top of the validation record. The FTDT freeze correction passed review, the full matrix and iOS FTDT acceptance. Android stopped at a startup setup blocker: the chosen API 30 image has WebView 91 and cannot parse the bundled Blazor bootstrap. Use a fresh current-WebView image for the next Android run. The remaining iOS isolation, theme/recovery and anonymous push checks subsequently passed on revision 5aa435f6 (run 10); see the validation record for exact evidence. Android API 36/WebView 133 subsequently passed startup and initial locked/rejected sign-in checks (run 11), then stopped when the mock server backed up ADB reverse connections. Closing the owned fixture restored shared ADB without a restart. The fixture TLS regression was reproduced and fixed in d2138bea (13 fixture tests / 2,937 Debug tests passed). Run 12 passed sign-in and kept HTTPS/ADB responsive, then stopped at a native Android SIGABRT: an invalid JNI global reference during post-login background work. The tombstone, logs and screenshots are preserved in the validation record. Isolate and review this native failure before resuming; unfinished Android acceptance continues to gate the final PR. The display ownership correction (b29b0f9d) passed a native stress test, but run 14 crashed after DAL sign-in during background member loading. A second isolated probe reproduced concurrent MAUI battery/Sentry enrichment failures. Correction c323ac80 serializes that SDK processor on Android and passed 16,000 native calls, the four regression tests, and the full validation matrix (2,943 Debug / 2,927 Release / 4 Docs). Run 15 passed the crash replay, account/cookie isolation, theme recovery, delayed catalogue/PDF, and expired/locked/ rejected session checks with no native crash. It stopped when new target 2887cfb4 (PRs 2536/2537) produced modify/delete conflicts in the removed DataManager and its prefetch tests. Port the cache behavior to the service-layer owners before validating and resuming on the reconciled tip; do not restore the monolith. Interrupted sign-in, stalled request deadlines, slow/offline logout/anonymous push, and FTDT duplicate-error checks remain unverified on Android. Exact results, conflicts and cleanup are in the validation record. The authorized reconciliation subsequently landed in 8fb3181f: PR 2537 behavior lives in the extracted document services; the monolith stays deleted. The full matrix passed (2,958 Debug / 2,942 Release / 4 Docs; four builds with 0 errors). Resume device acceptance on this reconciled candidate, iOS first. Resolution details and hashes are in the validation record. The reconciled candidate then passed every applicable walkthrough: iOS run 16 followed by Android run 17, including interrupted sign-in, native cancellation deadlines, slow logout and anonymous push, disconnected Android logout, and FTDT single-error reporting. Installed artifact proofs and screenshots/logs are recorded at the top of the validation record. Both owned devices were deleted and their processes stopped. Step 4 is complete; proceed to the final PR and its required human approval.

Walkthrough What it must show
Account switch through Blazor logout → login B never sees A's cached menu, favorites, documents or web cookies; theme follows B's MEC. No-logout switching is N/A: the user confirmed it is not an app flow.
Interrupted Blazor sign-in after logout (kill mid sign-in) next launch comes up logged out or as the member whose credentials were stored; no crash loop; no A data
Rejected / locked credentials one Session Expired or Account Locked dialog, credentials handled per RefreshFailureKind
Slow or offline logout completes; push re-registered anonymously afterwards
Resume with expired session silent refresh; stalled socket retries within the 15 s / 60 s envelope
Home, theme, feed recovery placeholder before fetch; no stale theme after MEC change
Document viewer catalogue GET may take up to 30 s (DocumentsApiClient.Policy); download and open
FTDT synchronization duty periods sync; no double error reports
iOS cancellation / cross-host redirect native cancellation honoured; bearer not sent to untrusted origins

Use a simulator or emulator created for the run, not one already in use; validate the installed bundle is the build under test (ALPADocs.dll mtime) before starting.

5. Open the final PR

Integration branch → imp/blazor-hybrid (one approver required). Reference PR 2527's description and the ledger. Do not enable auto-complete until step 4 has passed.

Pre-existing defects found during the review, filed separately and not gates for this integration: AB#2857 (push tags left in memory by AppProperties.Clear()), AB#2858 (Notification Hub tags not updated on member switch), AB#2859 (slow GLOBAL theme overwriting a newer MEC theme), AB#2860 (whole-file pre-commit secret scan).

Validation of the reconciliation branch

Recorded from the run on d8bbed76 (the earlier run on 55d37173, before PR 2534, gave 2,904 / 2,898 / 4 with the same build results); see the validation record for the matrix definition.

Check Result
Debug unit + architecture 2905 passed, 0 failed, 0 skipped — reconcile02-debug.trx 0a531a997e274d2779921265e1e48bf650a04e69cf220dde24ac3748bc29644d
Release unit + architecture 2899 passed, 0 failed, 0 skipped — reconcile02-release.trx 5429794b14c0ba558df34f39320978ad5bde40d0b25e66ba3a2aab99701327a2
Documentation tests 4 passed — reconcile02-docs.trx c098818f9fc427fb045f69f05099fc4e6b17a7bf77b7c1a3ca0df1c676e70cac
ios-debug / android-debug / ios-release / android-release all built, 0 errors (650 / 676 / 653 / 679 warnings; 6.2 s / 40.6 s / 15.6 s / 78.5 s)
Navigation freshness, gateway catalog nav regions current; 75 routes, 0 gaps; catalog regression test passed

Same counts as PR 2527's tip ce46a36a (2,904 from be3c7a10 plus PR 2534's one test): the reconciliation added no tests and broke none. Build success is compilation evidence only; device acceptance (step 4) has not been run.