Implemented in d30a8d907700b5f7f10280430ae01ea744e0f0dd and follow-up 342d355e33f57673721dbc10207e67845806e0fb. The confirmed theme-network wait is removed. Logged-out Home resolves through the existing orchestrator using cached/embedded styling, renders its content and Login action, then refreshes live theming after render. Baseline → CMS page-theme ordering remains intact. Member changes, disposal and accepted content replacement cancel the background work; theme publication checks cancellation even after a cache write. Final logout cleanup retires the interim cache generation, so its same-anonymous-context completion notification now restarts theme/content reconciliation without clearing the visible Home.
The first corrected device probe exposed that final-cleanup edge case: Home was fast but one live theme request never started. That run stopped, and the additional regression failed before the follow-up. The final candidate passed 108 focused tests, including six added cases covering pending live I/O, theme ordering, member change, disposal, cancellation during baseline/page cache writes, and cleanup completion. Normal code-commit hooks passed without bypasses. The original red TRXs and stopped device evidence are retained.
Revision 342d355e33f57673721dbc10207e67845806e0fb; source tree 70f3869ad040cbf9af5dbd7c0c40ec3d8d54726b. Target remains 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32.
| Suite | Passed | Failed / skipped | TRX SHA-256 |
|---|---|---|---|
| Debug | 2,985 | 0 / 0 | 7dfda93c23916c426fb2cf5f67c7c14e1117f99aaa03f32ee4966de3d2951d2b |
| Release | 2,969 | 0 / 0 | 596104be46f8670727883d283cc38d4860e85a649161453e73d5e9e17e85fba3 |
| DocsTests | 4 | 0 / 0 | c6b3278cba2486e975a22cf8b838b838d139cc22039e60c0830e6a50e4678b84 |
TRXs: theme38-matrix-debug.trx, theme38-matrix-release.trx, theme38-matrix-docs.trx. iOS Debug/Release builds: 0 errors, 650/653 warnings; Android Debug/Release: 0 errors, 676/679 warnings. Navigation is current; gateway catalog 75 routes / 0 gaps; catalog regression and 4 logout browser tests passed. The signed, nonincremental iOS acceptance build had 0 errors / 676 warnings. Installed head, executable, Presentation and Application hashes/mtimes and signature were verified before launch; the preserved signed bundle was independent of subsequent matrix build outputs.
Dedicated iPhone 17 Pro Max / iOS 26.5, LogoutTheme38, UDID 5F88D795-9BD2-47E1-9E28-3AA37CBA98D1. All inputs were native taps. Timing starts at the trusted click; Home means the logged-out content/Login DOM is available, not completion of separately loaded remote images. No logging-out message or visible Blazor error appeared.
| Controlled GLOBAL response | Home before correction (run 35) | Home now | Anonymous tabs now |
|---|---|---|---|
| Normal | 75 ms | 57 ms | 69 ms |
| Site HTTP 200 delayed 3 s | 3,057 ms | 61 ms | 70 ms |
| Theme HTTP 200 delayed 3 s | 3,705 ms | 54 ms | 67 ms |
| Site HTTP 401 delayed 3 s | 3,215 ms | 54 ms | 61 ms |
| Normal restored | 533 ms | 74 ms | 88 ms |
The delayed replies were recorded after Home appeared. Distinct fixture-only color values proved successful live themes actually applied after cleanup. A separate logout → DAL login → MEC navigation reached the DAL theme in 11.473 s; both old GLOBAL responses, delayed 12 s, then returned HTTP 200 without changing the DAL theme. An earlier 30 s fixture attempt hit the existing 15 s client deadline and was correctly cancelled; it was not used as evidence of a late successful response. A helper initially missed the MEC tab because it searched button,a while the actual control is a div[role=button]; the corrected driver used its real geometry/native tap. Both stopped driver attempts remain in the evidence.
Fresh live simulator AB2081-ServiceLayerIntegration01-LogoutLive37, UDID D2803ADA-1761-4B85-9DAF-4956B98FD988, used the same signed candidate with no fixture override and the approved vault accounts. Actual HTTP 200 menu responses were compared with the rendered tabs for both signed-in members and their post-logout anonymous menus:
| Account | Live signed-in tabs | Home after logout | Anonymous tabs after logout |
|---|---|---|---|
| UAL | HOME, SUBMIT, JUMPSEAT, KCM, UAL MEC | 24 ms | 29 ms |
| DAL | HOME, DART, JUMPSEAT, STS, DAL MEC | 24 ms | 33 ms |
No empty bar was observed. Cold anonymous startup used the local fallback and issued no menu request in that capture; it is not claimed as a live API comparison. The first live UAL probe recorded Home at 31 ms and anonymous tabs at 36 ms, failing an old same-DOM-mutation assertion. The final checks measured both independently against the existing 250 ms paint budget, preserving that original trace. The older 1,363 ms route-navigation outlier remains unattributed; this correction specifically removes the confirmed theme dependency.
The diagnostic simulator was deleted and its fixture/automation stopped. The new live DAL simulator remains on /alpa with a settled feed, correct five-item menu and no Blazor error; its Appium/log collectors are stopped. Existing review simulators were untouched.
This run rechecked the affected iOS Home/theme/member flows. The earlier full iOS and Android walkthroughs below retain their original revisions; they were not all repeated in this correction run. Android Debug/Release builds and shared regressions passed, but this run adds no Android-device result. PR 2543 remains open for human review with auto-complete off; no votes were cast. Do not treat this record as a merge approval.
Local evidence (not uploaded CI artifacts):
/private/tmp/AB2081-theme38-matrix/; manifest SHA-256 265786d585f6563c0c4f3d2c2bb8b0590e6136d3daa7dc0225dab83ec160a4b5./private/tmp/AB2081-ServiceLayerIntegration01-logout-theme38/; manifest SHA-256 0ce667f8e2aa96c0e2fa62a88f16638a4f98d80984a24334249c1fd977a92b61./private/tmp/AB2081-ServiceLayerIntegration01-logout-live37/; manifest SHA-256 d0f69ff81415b625a99a7ba80bbcbed417ab2a6987bf7a75dee5617315c6bcbe.Record-only DocsTests: 4 passed, zero failures/skips; theme38-record-docs.trx, SHA-256 98f285a70c7b9649f3d991872f869642ec6a425ee3c0704b5c15b9add46f3a47.
Historical finding, corrected in the section above. Functional acceptance below remains recorded; at this investigation revision, complete logged-out Home was delayed when GLOBAL theme requests are slow. PR 2543 remains open with auto-complete disabled. No application code was changed in this investigation.
Candidate 8f2d6c4f5a10b7d86da87aff75080980fef24f21 differs from the full-matrix candidate f277bd9bf959e41656f2bf3fbbeab60bfb8b75d5 only in documentation. A fresh owned iPhone 17 Pro Max / iOS 26.5, AB2081-ServiceLayerIntegration01-LogoutTheme35, UDID D09DF536-2AC2-4AB7-B3C4-EC09EFB0090F, ran a signed nonincremental Debug build: 0 errors / 676 warnings. Installed head, executable and Presentation hashes/mtimes and signature matched before launch. All accounts and delayed responses were local synthetic fixtures; the live DAL review simulator was untouched.
AlpaIHomePage.LoadLoggedOutFeedAsync reads the embedded page locally, then awaits DynamicPageOrchestrator.ResolveAsync before assigning components. The orchestrator awaits ThemeCoordinator.EnsureThemeAsync, followed by the page theme when present. EnsureThemeAsync applies a local placeholder but still awaits its live resolution task. ThemeApiClient.FetchAsync resolves the GLOBAL site and its active theme through the live-first clients. Logout invalidates the memoized resolution's context, so visiting Profile beforehand does not guarantee a warm theme for the new anonymous context.
The result is a network dependency in the supposedly local-first Home paint. Navigation and anonymous tabs can already be correct while components remains null and HomeSkeleton stays visible. The 250 ms paint-wait timeout releases cleanup; it does not make the blocked content resolution complete.
Only GLOBAL site/theme response delay/status changed between these five native-tap cases:
| Case | Route | Anonymous tabs | Complete Home | Largest 50 ms JS timer gap |
|---|---|---|---|---|
| Normal fixture responses | 19 ms | 23 ms | 75 ms | 53 ms |
| GLOBAL site HTTP 200 delayed 3 s | 17 ms | 22 ms | 3,057 ms | 55 ms |
| GLOBAL theme HTTP 200 delayed 3 s | 222 ms | 266 ms | 3,705 ms | 97 ms |
| GLOBAL site HTTP 401 delayed 3 s | 82 ms | 101 ms | 3,215 ms | 64 ms |
| Normal responses restored | 94 ms | 110 ms | 533 ms | 66 ms |
In the delayed-site case, the request started 21 ms after the trusted click, returned at 3,030 ms, and Home appeared 27 ms later. CacheDatabase had already reported its security-trimmed index purge complete at 292 ms. In the delayed-theme case, the theme response arrived at 3,622 ms, 83 ms before Home. Screenshots show the skeleton and anonymous three-tab bar during the wait. No visible Blazor error or logging-out message appeared. The sampled WebView event loop continued throughout the waits; these reproductions did not show a multi-second UI-thread freeze.
This confirms a mechanism capable of producing the original live 3.5–4 s content delays. Those original cycles did not retain stage-level managed/HTTP timing, so their exact time breakdown is not reconstructed. The separate 1,363 ms UAL route-navigation outlier is not attributed by this probe; route time here was 17–222 ms.
Keep the existing orchestrator and theme coordinator as the owners. Give the logged-out initial render a genuinely local theme path using cached/embedded public styling, publish the embedded Home content immediately, and reconcile the live theme/content afterwards. Retain the current session/generation guards so a late anonymous response cannot overwrite a newly signed-in member's theme. Do not globally remove theme ordering from MEC pages.
Add a component regression that holds GLOBAL theme resolution pending and asserts that the logged-out Home and Login action render before that task is released, plus a late-result member-switch check. Existing Profile tests verify navigation/cleanup ordering and the orchestrator tests use an immediately completed theme fake; neither proves initial Home content is independent of theme I/O. After correction, repeat the delayed-site, delayed-theme and unauthorized-response cases and live UAL/DAL logout checks before clearing this concern.
Evidence: /private/tmp/AB2081-ServiceLayerIntegration01-logout-theme35/, including probe-results.json, diagnostic-summary.json, pending/complete screenshots, native logs, HTTP events, signed-bundle proof, build log and copied driver scripts. Manifest SHA-256: 9d6ca7a36db9d08fc4fb9814ca9af9ee0d7547a83dfe92d432c65531c2bc4275. The diagnostic simulator was deleted and its owned fixture, Appium and log processes stopped. These are local artifacts, not uploaded CI evidence. Documentation validation: 4 passed, zero failures/skips; logout-theme35-docs.trx, SHA-256 ccf349ada359e3fe695b1b418b301f052f234ab26a503cbcd70e86e8b8bc0c49.
The user verified that Profile works and authorized continuing acceptance. Live native taps now reached Profile for both UAL and DAL (trusted click to route: 36 / 33 ms). The earlier run-32 timeout remains preserved below; its initial input delivery was not recorded, so no root cause or application correction is claimed. It is not carried forward as an unresolved walkthrough after the user's verification and this instrumented continuation.
Application candidate f277bd9bf959e41656f2bf3fbbeab60bfb8b75d5 is unchanged. Continuation branch revision b19774039a1fdb828f3e29d3cb70c42210ae9a80 adds only the previous evidence record. Target remains 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32. The full matrix recorded below remains valid: 2,979 Debug / 2,963 Release / 4 Docs, four builds with 0 errors, current navigation and 75 gateway routes / 0 gaps. No device result is inferred from a build. All applicable runbook walkthroughs are now complete on this application candidate; PR 2543 still requires human approval. No votes were cast and auto-complete remains disabled for review.
Fresh owned iPhone 17 Pro Max / iOS 26.5 MockAcceptance33, UDID C41F45E9-35B8-4FEF-ADEF-02CAF6CE6B66, completed the remaining expired-rejected-session case: exactly one refresh, one Session Expired alert, both stored credential entries removed after positive presence baselines, and no visible Blazor error. Installed signed head/executable/Presentation hashes and mtimes were checked before launch and resume. Together with controlled run 30 below, this completes the iOS runbook cases.
Live continuation 34 used the owned LiveMenu32 simulator, UDID 69C9BAC9-993F-4F64-8033-FF2D18B542E2, after rechecking its installed build. It used production API responses and approved Key Vault UAL/DAL accounts, with no fixture override. Both returned HTTP 200 menu responses (37 records), rendered the exact applicable rows, and returned to the three anonymous tabs after logout. No sampled bar was empty.
| Context | API-backed rendered tabs | Menu HTTP duration |
|---|---|---|
| UAL | Home, Submit, Jumpseat, KCM, UAL MEC | 1,148 ms |
| DAL | Home, DART, Jumpseat, STS, DAL MEC | 1,046 ms |
| Anonymous after UAL / DAL | Home, Jumpseat, KCM | 442 / 367 ms |
The four-item fallback transitioned to the authoritative five-item live menu for each MEC. The DAL bar in the controlled fixture is artificial and is not used as menu-correctness evidence. Response-body SHA-256s: UAL 7b15c9c2e5f649243ae81ddfca2e1d8f636364264d0f16655a7d439b23f14510; DAL b1f98c01c342563a6ee44ac91b05ae7d849f05ebdbf7899863726ed133f6a402; anonymous b3d67fb371f5aa2e0560b875198b4a6aa8523b6cd97fe46c8ffbd9a4e5d1a8f7.
Logout timing qualification: live UAL/DAL content paint took 4,009 / 3,514 ms. These are retained observations, not replaced by the faster diagnostic. Route/tab transition was separate: UAL 1,363 / 1,417 ms, DAL 13 / 45 ms. A standalone DAL diagnostic then showed route 15 ms, anonymous tabs 18 ms, complete anonymous Home 178 ms, with video and DOM trace retained. No lockup or logging-out message was observed. The device checks establish functional recovery; they do not establish consistently subsecond live Home content paint. The original slow samples remain available for performance review.
Both iOS drivers initially found the rendered app while the CDP bridge was not ready; relaunching the same verified bundles restored it. The controlled Appium session also needed its startup retry. These happened before the walkthroughs, required no application edits, and are retained in the driver logs.
Owned Pixel 9 / API 36 AB2081-ServiceLayerIntegration01-AndroidAcceptance31, with a private ADB server and WebView 133.0.6943.137. The signed nonincremental APK was pulled back and hash-matched; its embedded ALPADocs.dll bytes/hash and build mtime were verified. Every launch/resume rechecked the installed APK. APK SHA-256: 104c35d8eb39d2a7d2c63f8bcfc191f76264dd95bd2a876b214fa7400dec6d79; embedded head DLL SHA-256: 0582147e98c54804993122ed69783a81b21c1bf12629d4d8f7952acafc74da9d. Only synthetic accounts reached the local HTTPS fixture; its CA was installed only in this disposable emulator, retaining system roots and normal TLS validation. Interactions used native taps.
| Walkthrough | Result |
|---|---|
| Locked / rejected sign-in | One authentication request and inline error each; successful UAL recovery. |
| UAL → DAL / DAL → UAL isolation | Outgoing menu, favorites, documents and native cookies absent; positive cookie baselines retained. |
| Home / theme / feed | UAL #12233e → neutral placeholder → DAL #002a50, no stale outgoing theme. |
| Document cache | Live updates, budget-one backfill, exactly two downloads, hidden AppContractLink category. |
| Catalogue / PDF | HTTP 200 after 29.010 s; positive rendered canvas and screenshot. |
| FTDT | Synced duty period rendered; real cumulative/duty tab taps responsive. Outage: three HTTP attempts, one native error report. |
| Slow logout / push | Pending catalogue canceled; anonymous registration HTTP 200 with native token, not a seeded token. |
| Disconnected logout | Connectivity positively changed Internet → None; anonymous Home returned. Remembered credentials preserved per Profile's ClearStoredCredentials=false; network restored. |
| Interrupted sign-in | Intentional process stop during pending authentication; recovered without outgoing DAL identity or crash. |
| Expired success | One silent refresh, Home recovered, no native session alert. |
| Expired locked / rejected | One refresh and one appropriate native alert each; both credentials removed after positive presence baselines. |
| Stalled native request | Attempts 14.928 / 14.929 / 14.940 s, total 51.087 s; inside 15 s / 60 s envelope. |
| No-logout switching | N/A, confirmed by user; not an application flow. |
Android trusted logout-click to anonymous-Home observations ranged 262–397 ms. No logging-out label or empty anonymous tab bar was observed. Final native crash buffer was empty; the process stayed unchanged after the one intentional interrupted-login restart. The FTDT driver initially rejected .NET seven-digit fractional timestamps. Its preserved events were read with normalized fractional precision. The streaming log repeated identical timestamped entries three times; the native log snapshot independently contained exactly one exception. The outage was not rerun. Both failed driver checks and raw records remain. The controlled iOS and Android devices and their owned fixture/driver processes were removed. The live iOS simulator remains on settled DAL Home for user review; Appium is stopped. Protected worktrees and the user's original simulator were untouched.
The final documentation record passed 4 DocsTests, zero failures/skips; acceptance34-final-docs.trx, SHA-256 95a1e97c24d04c0c2ab4ccad0f7aa684a5327a4c5c04286898a32e44ad51f25c.
Full matrix commands, counts, build results and TRX SHA-256s remain in the next section. Evidence is retained locally, not uploaded CI artifacts:
/private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance33/: rejected-expiry result, alert screenshot, installed proofs and driver logs./private/tmp/AB2081-ServiceLayerIntegration01-live-menu34/: live response metadata, transition samples, trusted input, logout diagnostic/video and settled DAL screenshot./private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance31/: all result JSON, native screenshots/trees, complete logs, installed APK proof, scripts and cleanup record.| Evidence manifest | SHA-256 |
|---|---|
| iOS rejected expiry | bd5f2a866085a4595b966db07d5baab9fe8895188baceec9458ab08eea7a55f1 |
| Live UAL/DAL continuation | 109bd0a503939836021df387e006e4d1d92bb10ff27f4a92cc2712c5823cd5fe |
| Android | d2ee252962018f2fe2f973ae51acd65d00317cec3c0c3af6c4e48e4265c7d77d |
Historical snapshot: the continuation above supersedes this section’s remaining-work list.
Candidate f277bd9bf959e41656f2bf3fbbeab60bfb8b75d5, target 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32. Application source stayed clean and unchanged. This record supersedes earlier acceptance claims for the current candidate. PR 2543 remains gated; auto-complete stays disabled.
All Reproduction commands ran sequentially with one MSBuild worker and node reuse disabled. Full logs and unique TRXs were retained. No tests failed or were skipped.
| Suite | Passed | TRX | SHA-256 |
|---|---|---|---|
| Debug | 2979 | candidate30-matrix-debug.trx |
0c0badf251948ce8f5c3e65ab3a714c37cd84e8be60a42687680eb7d0ee15029 |
| Release | 2963 | candidate30-matrix-release.trx |
9038e962993bcb6271ffeb159f040daed8d4e9f7bc8fe2a27823f4d4c309c53d |
| Docs | 4 | candidate30-matrix-docs.trx |
16a52623e5f9ffea26ac757e768eb61e4edaa64ad269ac221b9efe8df3a6dc8c |
| Build | Errors | Warnings | Wall time |
|---|---|---|---|
| ios-debug | 0 | 650 | 8.18 s |
| android-debug | 0 | 676 | 44.2 s |
| ios-release | 0 | 653 | 16.33 s |
| android-release | 0 | 679 | 83.73 s |
Navigation regions are current. Gateway catalog: 75 routes / 0 gaps; its regression passed (1 test). Browser logout-paint regressions: 4 passed. Additional signed iOS Debug and embedded-assembly Android Debug device builds used --no-incremental; both had 0 errors. The Android APK was built, but no Android acceptance device was launched after the iOS stop.
Dedicated iPhone 17 Pro Max / iOS 26.5 MockAcceptance30, UDID 81A41C83-448D-4D43-9BAF-C63ED69B6C31. Installed head, executable and Presentation DLL hashes/mtimes matched the signed build before launch. Installed proofs were rechecked before each explicit relaunch/resume. Only synthetic UAL/DAL accounts reached the approved local HTTPS fixture. Appium native taps, screenshots/trees and fixture requests provide evidence.
| Walkthrough | Result |
|---|---|
| Initial locked / rejected sign-in | Passed: one request and one inline error for each; successful UAL sign-in afterwards. |
| UAL → DAL and DAL → UAL isolation | Passed: outgoing menu, favorites, cached documents and native cookies absent after positive baselines. |
| Home / theme / feed recovery | Passed: 20 sampled states, UAL #12233e → ALPA placeholder → DAL #002a50; no outgoing UAL brand after switch. |
| Document cache | Passed: live cache updates, budget-one backfill, exactly two downloads, AppContractLink category hidden. |
| Catalogue / viewer | HTTP 200 after 29.012 s; PDF visibly rendered on an 880 × 1138 canvas. |
| FTDT | Fixture duty period rendered; native duty/cumulative taps responsive. Controlled outage: three attempts, exactly one native error report. |
| Interrupted sign-in | Passed: killed during pending authentication; recovered to anonymous Home without outgoing identity. |
| Slow logout / anonymous push | Passed: pending catalogue canceled, anonymous registration HTTP 200. Home DOM appeared 90 ms after the trusted click with anonymous tabs and no logging-out message. |
| Expired-session success | Passed: one silent refresh, no alert; signed-in Home and remembered credentials retained. |
| Expired locked session | Passed: one Login Issue alert/refresh; both credential entries removed after positive presence baselines. |
| Stalled request / cancellation | Three native cancellations at 14.987 / 14.983 / 14.990 s, total 51.071 s. |
| iOS cross-host redirect | Passed: initial request carried authorization; approved sink received none. |
| Expired rejected-session resume | Not run after acceptance stopped. |
| No-logout switching | N/A, per the user's confirmed app flow. |
| Android device acceptance | Not started; iOS acceptance did not complete. |
The slow-online case covers the runbook's slow-or-offline alternative on iOS; no disconnected iOS result is claimed. Controlled logout click-to-Home times were 64–118 ms. Secure-storage probes recorded presence booleans only. Two harness pauses were diagnosed: the expected DAL cache opt-in dialog blocked the menu hit-test, and the catalogue repaint briefly blocked the document hit-test. The visible Not Now button dismissed the dialog; the document tap waited for a reachable control. Original driver logs remain preserved.
Fresh LiveMenu32, UDID 69C9BAC9-993F-4F64-8033-FF2D18B542E2, used the same candidate with no endpoint override. Installed hashes/mtimes and signing were verified. Approved UAL credentials came from Key Vault; no vault credentials reached the fixture. Anonymous and UAL HTTP 200 responses matched the rendered bars. UAL rendered Home, Submit, Jumpseat, KCM, UAL MEC. Observed tabs changed from three anonymous items to the four-item UAL seed and then five live items, with no empty sample recorded.
At 12:39:28 UTC, the native Profile tap at (292, 89) returned success from Appium, but the app remained at /alpa; Profile did not appear within the 35-second wait. The native screenshot showed Home without an alert or visible Blazor error. The first tap had no DOM input recorder, so delivery to Blazor is unverified. A later diagnostic tap at the same coordinates recorded trusted pointerdown, pointerup and click events and reached /profile. That success does not explain or clear the initial failure. No native crash or permanent freeze is established. Cause remains unresolved; acceptance stopped rather than retrying to green. No application fix was made.
Fresh live DAL menu/logout acceptance is therefore unverified. The DAL bar seen in MockAcceptance30 (Home, Jumpseat, KCM, DAL MEC, PDR) was diagnostic fixture data, not a live DAL response or menu-correctness pass. The previous live DAL result below is historical. Remaining: diagnose the initial Profile-tap timeout, then resume live UAL/DAL cycles, expired rejected-session recovery and Android walkthroughs.
The documentation record passed 4 DocsTests, zero failures/skips; candidate30-acceptance-record.trx, SHA-256 7cb844256d77662c998b47524149271da0757167782b869103d32ef6d93d6917.
/private/tmp/AB2081-candidate30-matrix/ (full logs, command arrays, copied TRXs)./private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance30/./private/tmp/AB2081-ServiceLayerIntegration01-live-menu32/, including acceptance-stop.json, live-verification-driver.log, live-check-stopped.png/.xml, profile-probe.json, live-ual-response.json, installed proof and Appium log.These are retained local artifacts, not uploaded CI evidence. The controlled simulator and fixture were deleted/stopped. The live failure simulator remains on UAL Profile for investigation, with its test driver stopped. Original review simulators and protected worktrees were untouched.
| Manifest | SHA-256 |
|---|---|
| Matrix | 6796c4939d77cbd094908ea304ee8f3530b76fe1e2f74ba996ab56d6319f7c5e |
| Controlled iOS | a96884c6edfd24eeba02f260a5d2412243ae1ef7b0ffc59ad2aedf2338961308 |
| Live iOS | 4c0716293314f1b40fe0ea071a8ac89279d933058761f7e8d64cbf9b7ba932ac |
Correction bea087e699575d74902a877e1a5574390415e265 removes the disabled PDR seed slot. The fallback order is Home, Jumpseat, KCM, member MEC; the last slot retains alpa-nav-icon--mec-alpa / nav-mec-alpa.svg. Live menu responses continue to replace this fallback. Tests cover UAL, DAL and unknown-MEC labels, exact route order and the glyph.
seed-menu-debug.trx, SHA-256 bca187c46ef8aeb4b6c759d1d7191253366ea2136fbaf64b169d3f6c46c64a8a.seed-menu-release.trx, SHA-256 87c0e11695bc5029a4f36a1c5dd9daa89e2a0c82384224c2b6acbc07a8571eae.seed-menu-docs.trx, SHA-256 e7930d410bf040f2814d133d2d11386fda3e2c235d0c823e181fa6547a299586.--no-incremental: 0 errors, 676 warnings. Head, executable and Presentation installed hashes/mtimes matched before each simulator launch.This explicitly requested seed preview uses a synthetic UAL identity with the local menu endpoint returning 503, so a successful API response cannot replace the fallback during review. It is not a live API acceptance result. The earlier live UAL simulator/session was preserved. The narrow test simulator was deleted after verification; the wide preview AB2081-ServiceLayerIntegration01-SeedMenu28, UDID 58858044-14B9-4FB7-860C-A36FF1950EA3, remains running with the four-item bar visible.
Evidence: /private/tmp/AB2081-ServiceLayerIntegration01-seed-menu28/, including seed-393.png, seed-440.png, both geometry JSON files, installed-bundle proofs, source patch and fixture state. TRXs: /private/tmp/AB2081-seed-menu28-tests/. The unchanged application source matched the pre-commit candidate based on 30fd7e07. Normal code hooks passed; PR 2543 auto-complete remains disabled pending review.
Correction cd390aee51e92219ac693bf57cbc58c367b4f26a implements the requested immediate logged-out Home transition, without a logging-out message. Live-response regressions are committed in af2d527957083354bf76b12b98442789b0f7539c. Identity, token delivery and the outgoing cache generation are revoked synchronously. Profile then navigates to anonymous Home; a bounded local paint acknowledgement precedes background cache/file cleanup. New session publication remains blocked until cleanup finishes. Native cookie work is dispatched to the UI thread; forced recovery retains its existing eager purge. The browser wait ends after two Home animation frames, backgrounding, or 250 ms; the interop call has a one-second cancellation budget. A failed transition is recorded and cannot cancel cleanup.
The bottom bar recomposes at the immediate navigation, the drawer removes outgoing rows and unread state, and late drawer responses are rejected by session epoch. Cleanup's final notification cannot redirect someone who already navigated while signed out in that epoch.
At the user's request, the synthetic checks below were followed by real gateway validation with the approved UAL/DAL Key Vault test accounts. A fresh install removed synthetic state, all synthetic secure-storage entries and the endpoint override. Before launch, installed assembly mtimes/hashes and code signing matched the tested correction. The app called https://gatewayapi.alpa.org/v2/api/mobilecontent/menuitems/getallforuser directly.
The anonymous and both member responses each contained 37 top-level records. The actual server-selected bars, in order, were:
| Identity | Live API / rendered tabs |
|---|---|
| Anonymous | Home, Jumpseat, KCM |
| UAL | Home, Submit, Jumpseat, KCM, UAL MEC |
| DAL | Home, DART, Jumpseat, STS, DAL MEC |
Four native cycles, UAL → DAL → UAL → DAL, matched the captured HTTP 200 response for that session and the subsequent anonymous response. Logged-out Home rendered at 128 / 128 / 143 / 141 ms after trusted clicks, already with the three anonymous tabs. No empty bar was observed. The member-menu requests took 1398 / 1445 / 1282 / 1296 ms; the existing startup seed is temporary while that request completes, not the expected final tab set. The application seed behavior was not added or expanded by this correction.
Four additional regressions replay sanitized captures through the production SDK, shared transport, mapper and tab composer, including repeated logout/member cycles. They preserve every record and mapped field, assert no record is discarded, and reject anonymous-seed fallback. Wire response hashes and provenance are in UnitTest/Fixtures/LiveMenu/. The live device checks above establish current network behavior; deterministic replay alone does not. Request headers, bearer tokens and account identifiers are excluded from captures.
Live artifacts: /private/tmp/AB2081-live-menu27/, including provenance.json, live-anonymous-device.json, live-cycles.json, verified installed bundle proof, and live-review-ready-profile.png. The simulator remains signed in on the approved live UAL account, with Log Out visible. The obsolete mock server was stopped. PR auto-complete remains disabled. A harness response-parsing error stopped before submitting credentials; its failed driver log is preserved. Azure Key Vault's expired login was refreshed interactively by the user; no credential-cache inspection was performed.
The earlier mock-menu setup returned diagnostic rows with showOnTabBar:false, replacing the startup seed with a valid empty tab set. Its first attempted tab fix also used embedded seed items instead of the SDK wire model's required children; the mapper rejected those rows. The corrected local fixture supplies three anonymous tabs and five member tabs with children:[]. These are fixture defects, not evidence that production menus intermittently return empty tabs. A legitimately empty server-selected tab set remains respected.
Dedicated iPhone 17 Pro Max / iOS 26.5, simulator 115E963D-B03F-4AB6-A7BC-FAE1E81D32C5, name AB2081-ServiceLayerIntegration01-LogoutFeedback21. The user's simulator was not changed. The signed Debug candidate was built with --no-incremental; head, executable and Presentation SHA-256/mtime matched the installed bundle before launch. Application sources were unchanged between that build and the correction commit; the source patch/manifest records the pre-commit candidate based on c1b3a990.
| Check | Observed result |
|---|---|
| Three one-document real-tap logouts | Anonymous Home DOM at 78 / 84 / 69 ms after trusted click; next animation frame 80 / 85 / 69 ms |
| Three 2,048-document real-tap logouts | Anonymous Home DOM at 77 / 112 / 77 ms; next animation frame 81 / 115 / 81 ms |
| Logout presentation | No logging-out label in any run; all three anonymous tabs present at first Home render; real Login tap worked after every logout |
| Native video | Captured and visually inspected Profile → public Home transitions, including the large-catalogue run; no persistent busy screen |
| Delayed menu / rapid member cycles | DAL → UAL → DAL → UAL, three-second menu delay each time; initial seed populated with the incoming MEC, then five server tabs; zero empty-bar samples; three tabs after each logout |
| Circuit health | No visible Blazor error in the measured logout or role-cycle checks |
| Initial mock handoff | Subsequently replaced by the live-API installation and review state above |
These are focused iOS checks on this correction, not a new full device-acceptance claim. Android runtime and both Release platform builds were not rerun for this correction. The exact cause of the user's originally reported intermittent freeze remains unconfirmed; this change removes the measured cleanup-dependent navigation delay. PR 2543 auto-complete remains disabled pending review and acceptance on the resulting revision. No-logout member switching remains N/A, as agreed with the user.
| Check | Result | Evidence |
|---|---|---|
| Debug unit + architecture | 2,977 passed, 0 failed/skipped | logout-live-final-debug.trx, SHA-256 05ce095a812ffa0e8cf188f55706df40d9f4c06382e5bbf1a157c7dc3991f540 |
| Release unit + architecture | 2,961 passed, 0 failed/skipped | logout-live-final-release.trx, SHA-256 4923f2687fd5cdb365b6b2a1f93e8621970f14ae87facb69ac2384772bfe8888 |
| Documentation | 4 passed, 0 failed/skipped | logout-live-final-docs.trx, SHA-256 6518f5c1650dceb372738093edee5e11b2d3161c4f290b35671b7e25ce812e3f |
| Browser paint regression | 4 passed | node --test scripts/presentation-tests/logout-navigation.test.mjs |
| Signed iOS Debug | 0 errors | ios-build.log, normal simulator signing, no incremental build |
| Android Debug | 0 errors | /private/tmp/AB2081-logout-final-android-debug.log; build only |
Sixteen added unit cases include four captured-live-response regressions. The other twelve cover revoked identity before navigation, blocked session publication, background synchronous disk work, transition failure, duplicate taps, observed cleanup, epoch-scoped late navigation, retained drawer state, stale responses and native cookie dispatch. Browser tests cover paint ordering, missing render timeout and background release. An intermediate attempt moved forced recovery's purge too late and failed its existing before-await isolation test; that attempt was corrected without weakening the test. The late-navigation regression failed before the epoch guard. Unique failed TRXs remain in the local test directory. No hook bypass was used for the code commit.
Local evidence: /private/tmp/AB2081-logout-feedback-tests/ (TRXs), /private/tmp/AB2081-ios-logout26/ (fixture and driver scripts), and /private/tmp/AB2081-ServiceLayerIntegration01-mock-logout26/ (installed proof, source manifest, trusted-click timings, per-cycle logs/screenshots, role-tabs.json, logout-feedback.mp4, and review-ready-profile.png). These are local artifacts, not CI uploads. Installed head SHA-256: 6a62f57512a6211c9cbaca349f9fc008d91991fca0ed7b851b8bc9835b3e1a21; Presentation: 1645a106ecc900e86e0749963497dcff3ac20887b7f4d2e98f1b426a523c1122.
Correction aa9bf7829ac75afc2ee7edf69c26fa5161e9b245 follows the user's report of intermittent logout freezes on an iPhone 17 Pro Max simulator running the integration branch. PR 2543 auto-complete is disabled pending correction review and acceptance follow-up. The earlier complete device record below describes 8fb3181f, not this changed application revision.
Read-only diagnostics from the user's simulator preserved the running process (PID 35908) and installed assembly hashes. Logout began at 2026-09-23T02:20:35.954979Z; private API/search cleanup finished at 02:20:37.5458Z, clearing 2,031 security-trimmed rows. A five-second native sample at 02:22:54 found the main thread executing interpreted managed code throughout, with allocations/GC rather than a network wait. Native sampling cannot name the interpreted C# caller; no managed debugger stack was supplied, so this is not a claim that the exact user hang has been conclusively attributed to one method.
Code inspection and regression tests confirmed a matching bottleneck: ClearCacheAsync loaded the document catalogue, then called an unindexed GetDocumentByFileId for every row, even when no file was cached. This synchronous work runs before logout yields when its mutation gate is free. The 2,048-row test made 2,048 redundant queries and took 4.115 s on the desktop runtime. Reusing the captured records reduced it to 0 queries / 0.022 s. These timings are diagnostic observations, not timing-sensitive test thresholds.
Bulk and category eviction now use each snapshot row inside the existing generation guard. The public single-file operation still resolves its file ID inside that guard. No logout ordering, credential policy, publication barrier or native-cookie behavior changed. The same correction removes every catalogued publication path when multiple rows share a file ID; the old first-by-ID query could leave another publication's file behind.
Three regressions cover a large catalogue without downloads, repeated file IDs with distinct publication dates, and context invalidation before deletion. The two original regression failures were inspected before implementation; both are preserved in ios-logout-bulk-red.trx.
| Check | Result / SHA-256 |
|---|---|
| Focused document/logout suite | 260 passed before the third regression was added; ios-logout-bulk-green.trx / d567201696c077396e7ba22ad64e5f33f75bd7e32e8e671b8be30dc839e70ce5 |
| Full Debug | 2961 passed, 0 failed, 0 skipped; ios-logout-full-debug.trx / a243f937e20c4d036c335f458639a9844e14532b97b5252d0ebf37b0acd18430 |
| Full Release | 2945 passed, 0 failed, 0 skipped; ios-logout-full-release.trx / 4c1fd900097ca2bd6d86d610bd465071f4b825bd95bb1f3df1233ab2f7539bd1 |
| iOS Debug simulator build | Signed --no-incremental build, 676 warnings / 0 errors. |
| iPhone 17 Pro Max / iOS 26.5 | Three successive 2,048-document logout runs: 1.211 / 1.299 / 1.208 s. Each showed anonymous Home, no Blazor error, and accepted a real Login tap afterwards. |
Native run AB2081-ServiceLayerIntegration01-LogoutFreeze19 used a fresh owned simulator and synthetic fixture accounts only. Confirmed hydration logs establish all 2,048 rows before each logout. Installed head assembly mtime/hash and signing verified; the corrected Infrastructure assembly also matched the build: d976c7097a82bf39e9f01acfa10793e8685712f9998725f160acbe71c8b531aa. The installed binaries came from the same application source committed above; the base revision and patch are retained in the run directory. The user's simulator was neither reinstalled nor restarted. The owned simulator, fixture and Appium process were removed.
Evidence paths: /private/tmp/AB2081-ios-logout-freeze/ (live sample, bounded logs, TRXs metadata) and /private/tmp/AB2081-ServiceLayerIntegration01-mock-logout19/ (installed proof, synthetic state, native screenshots, timing results and scripts). Large-catalogue result SHA-256: 1578eac94395f005a6e076b87d581be6c6649419a47f0258d6b0b1f5f65097d9; native manifest SHA-256: bccada13322da33e372d1ee3028def5ad01752213bbf3f384b90995b42213b54. These are local artifacts, not uploaded CI evidence.
Harness setup corrections: run 18's copied fixture expected an existing endpoint and stopped before app launch; its owned simulator was deleted. Run 19 selected its listener by PID/port, because the broker shares identities between builds of the same project. The hydration-log parser was corrected for variable timestamp precision before logout measurements began.
The documentation update passed 4 DocsTests, zero failures/skips; ios-logout-correction-docs.trx SHA-256 bd6a2cd307f3e157e009a3346a6c9c2ca03afa521cf9cde3d4cb21c62c74182a. Normal code-commit hooks passed 52 architecture checks and all 2,961 Debug tests.
This focused verification does not replace the full integration acceptance matrix on the new revision. Keep auto-complete disabled while the correction is reviewed and the user's reported scenario is retested; the exact managed stack remains useful if a freeze recurs.
All applicable runbook walkthroughs passed on application 8fb3181f1cefe66018305ac5dda917a0ec6fddfb, with documentation-only branch tip c10e6ed76ec48137e21696f9f8a3d138506949bd. iOS ran first on dedicated iPhone 15 Pro / iOS 26.5 simulator run 16; Android followed on Pixel 9 / API 36 / WebView 133 emulator run 17. These results supersede the open acceptance gates in the historical records below. No application code changed during either run.
The user-approved TLS fixture used synthetic UAL/DAL accounts only. Real native taps drove Blazor controls; native screenshots/trees verified foreground pages and alerts. No vault credentials were entered into the fixture. No-logout member switching remains N/A, as confirmed by the user. The full matrix below remains 2,958 Debug / 2,942 Release / 4 Docs, four platform builds with 0 errors, and 75 gateway routes / 0 gaps.
| Walkthrough | iOS run 16 | Android run 17 |
|---|---|---|
| Initial locked / rejected credentials | One inline error and one authentication request for each attempt; successful UAL login afterwards. | Same; requests 44 / 46 for locked / rejected. |
| Account switch and isolation | UAL → DAL and DAL → UAL; outgoing menu, favorites and documents absent. Cookie request 272 positive, 347 absent after switch. | Same; cookie request 246 positive, 331 absent after switch. Previous crash sequence passed in PID 4264. |
| Home / theme / feed recovery | 21 captured states: UAL #12233e, ALPA placeholder, DAL #002a50; no outgoing brand retained. |
17 states, same transition; delayed DAL content recovered. |
| Interrupted sign-in | Terminated during pending authentication request 470; installed-build proof before relaunch; anonymous with no outgoing member data. | Terminated during request 559; recovered without outgoing DAL identity or native crash. |
| Slow logout / anonymous push | 0.647 s; pending catalogue request 621 canceled; anonymous registration 632 returned 200. | 0.988 s; pending request 463 canceled; anonymous registration 471 returned 200. Native registration baseline established on both platforms. |
| Disconnected logout | Slow-online alternative above fulfills the runbook; no disconnected iOS result claimed. | Connectivity changed from Internet to None; logout completed in 0.899 s and showed the anonymous landing. Remembered credentials preserved by the existing Blazor policy. Network restored. |
| Expired-session success | One silent refresh, request 703; no alert; authenticated home and credentials retained. | One silent refresh, request 836; authenticated home, no Blazor error. |
| Expired locked / rejected session | One native Login Issue / Session Expired alert, requests 810 / 911. Both stored credential entries removed after positive presence baselines. | One native alert each, requests 945 / 1060; both stored credential entries removed. |
| Stalled request envelope | Three native cancellations: 14.989 / 14.988 / 14.988 s; total 51.041 s. | Three cancellations: 14.914 / 14.943 / 14.942 s; total 50.992 s. |
| Catalogue / document viewer | Catalogue HTTP 200 after 29.008 s; downloaded PDF visibly rendered on a 786 × 1017 canvas. | HTTP 200 after 29.015 s; rendered PDF canvas 824 × 1066. |
| Cache backfill / coalescing / live refresh | Cache page updated without revisiting; budget-one backfilled the second uncached file; exactly two downloads; AppContractLink row hidden. | Same behavior and exactly two downloads. |
| FTDT synchronization / error reporting | Fixture duty period rendered; real duty/cumulative tab taps responsive. Controlled 503: three attempts, exactly one native error report. | Same; no freeze or native crash. |
| iOS cancellation / cross-host redirect | Native cancellation proved above. Request 458 carried authorization; approved sink request 460 received none. | iOS-specific redirect requirement; no Android redirect claim. |
Anonymous push delivery is evidenced by the slow-online case, not claimed while the network was disconnected. Secure-storage probes persisted only presence booleans. Android's final native crash buffer was empty. Its sole process restart was the intentional interrupted-login force-stop; earlier JNI-crash replay and repeated member changes completed without a crash.
Both device builds used --no-incremental. iOS source/installed ALPADocs.dll mtime matched at 1790126087958275286 ns and the installed signature verified. Android's pulled-back APK matched the source; the embedded DLL matched at ELF offset 16,384, source mtime 1790125809966806961 ns. Proof was checked before each explicit launch/resume.
| Artifact | SHA-256 |
|---|---|
| iOS ALPADocs.dll | c16febc8cf2779ccc7cea933efebe84db9616ccc87ae360b30ea1709c8cb2fe4 |
| Android APK | 1cafeedc688f78d8486d88e86170bbc305c21c1a2cc4721b28dedc319150b468 |
| Android embedded ALPADocs.dll | f1fdede4417e54864ca4979b1e87a3808ce9af1d02b386bf1c31c12c400ef573 |
| iOS acceptance-summary.json | 0c01e6af78705c4b791f39f0f0dcbda6478fe19cd1f021df3d7622604f2152cb |
| iOS hash-manifest.json | 35f520c14012466da2bde7ee7a81f9978cc7341714bc90c6fe5975192123d555 |
| Android acceptance-summary.json | 8488831bdb5207419a8406e7743a99fdfe8bafa48062c1d310fc66ff6f9ddaa7 |
| Android hash-manifest.json | d71da8ca2936597d735f8b99cf09744e7c6f3cfac10799854f38f3687543cc28 |
Full screenshots, native trees, request/cancellation timings, logs, result JSON, scripts and hash manifests remain local under /private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance16/ and /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance17/; these are not claimed as uploaded CI artifacts. The owned simulator and emulator/AVD were deleted; fixture, capture and private ADB process exits were verified. Shared devices, shared ADB, and the protected worktrees were untouched.
Harness corrections are retained in the evidence, not counted as product failures: the iOS cookie setter was restored before proving positive/negative isolation; document category and opt-in steps were handled; native overlays were closed before underlying taps; startup waited for the existing WebView. Android's initial offline assertion incorrectly expected credential deletion: ProfilePage.razor.cs explicitly passes ClearStoredCredentials=false. The corrected check proved logout and preserved remembered credentials. Locked/rejected refresh tests separately proved deletion. Chrome's first-run overlay after help was closed only on the owned emulator, without accepting terms or adding an account.
The target remained 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32 at the final acceptance check. The acceptance-record documentation passed 4 DocsTests, with zero failures/skips: reconciled-device-acceptance-record.trx SHA-256 b33837d39ecdbfb77a015235823d3e051ec693cd0e16b22f9107240c2842fb5a.
Step 4 is complete; the final integration PR may now use default-merge auto-complete, subject to the target's required human approver. No votes were cast.
Application merge 8fb3181f1cefe66018305ac5dda917a0ec6fddfb combines integration parent 719f6a8dab7670ca2a6b787164c3a4904aecedba and target 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32. The user authorized porting the new target logic after the run-15 stop. This supersedes the target-drift blocker below; the reconciled device acceptance subsequently passed as recorded above.
| Conflict / incoming behavior | Resolution |
|---|---|
Deleted DataManager.cs, changed by target |
Kept deleted. Ported its functional changes to the existing document services. Whitespace-only changes to removed concerns need no replacement. |
Deleted DataManager_PrefetchDocumentsTests.cs, changed by target |
Kept deleted. Ported backfill into DocumentPrefetchService_SelectionTests and completion behavior into DocumentPrefetchCompletionTests. |
| Prefetch budget backfill | Filter cached files before applying each category's count, preserving catalogue order and opt-out rules. |
| Duplicate downloads | DocumentCacheService shares a lazy producer for the same file path, generation and cancellation scope. Lazy execution prevents multiple factories starting I/O under contention; conditional removal preserves newer retries. Distinct cancellation scopes remain independent. |
| Member isolation | Retained generation checks around token acquisition, download, file publication and every joined result. A new member never joins the outgoing producer. |
| Tag-only cache row | Exclude AppContractLink case-insensitively from visible cache groups, retaining its catalogue entry and mandatory prefetch. |
| Live cache refresh | DocumentCatalogHydrator waits for both independently observed passes, then sends one completion through the existing messenger only if the member generation is current. Kept the incoming page subscription, renderer dispatch and dialog guards. |
| Retired debug tag seeding | Preserved the target's disabled call by making configuration preparation inert; backend options remain authoritative. |
| Auto-merged cache tests | Replaced legacy DataManager / CreateDataManager references with DocumentCacheService / CreateService. Kept incoming cache-view-model and page-refresh tests. |
| PR 2536 hotel icons / CSS | Retained all four SVGs and the hotel markup/styles. CSS blob 1fff23a76b30ba857ba98d6fc64d52e1ddf7dd1a exactly matches the target; no whole-file conflict replacement was used. |
Review covered retry eviction, simultaneous callers, cancellation isolation, old/new member producers, and completion timing across both pass orders. Seven expected red failures (246 passing) were recorded before the port; all 253 document-focused checks passed after. The final simultaneous-caller regression and full pre-commit run passed 2,958 tests. Normal hooks ran with no bypass: 52 architecture checks and 2,958 unit checks passed.
| Suite | Result | TRX / SHA-256 |
|---|---|---|
| Debug | 2958 passed, 0 failed, 0 skipped | pr2537-matrix-debug.trx / 6ecf43d88d67fdc5f5e244e559135ed0d59d6c29c39eabdd447de444302f4e22 |
| Release | 2942 passed, 0 failed, 0 skipped | pr2537-matrix-release.trx / 4aeda684797138268f71ed676142c1fc92016355e336352e97ed7043449c5590 |
| Docs | 4 passed, 0 failed, 0 skipped | pr2537-matrix-docs.trx / 069e983a9fd670ea3bc1bde3b726d9be63db8ff627c17dcbeaf9f47d87cf9f10 |
| Build | Result | Wall time |
|---|---|---|
| ios-debug | 650 warnings, 0 errors | 8.93 s |
| android-debug | 702 warnings, 0 errors | 151.12 s |
| ios-release | 653 warnings, 0 errors | 17.19 s |
| android-release | 679 warnings, 0 errors | 81.8 s |
Android Debug used --no-incremental and embedded assemblies for installed-artifact proof. Navigation is current; gateway catalog reports 75 routes / 0 gaps, with its regression check passing. Full logs, command arrays, TRX hashes and review evidence are local artifacts under /private/tmp/AB2081-pr2537-validation/; they are not claimed as uploaded CI artifacts. The new candidate subsequently passed iOS-first and Android acceptance, recorded above. Historical device runs below are retained for traceability.
Application c323ac801f9d522c995c6a124384ca38d01e1e14, validation documentation eff216458cb29f065da34fc320b3bf1a1eb19842, dedicated API-36/WebView-133 run 15. The previously failing sequence now passes: UAL sign-in, live Blazor FTDT, logout, DAL sign-in and DAL home. The app remained in PID 4727 through the completed walkthroughs, with an empty native crash buffer. No new app crash was observed. All accounts/data were synthetic fixture data; no vault credentials were entered on this emulator.
| Walkthrough | Result |
|---|---|
| Initial locked / rejected sign-in | Passed: one inline error per attempted sign-in; no Blazor error. |
| UAL → DAL crash replay | Passed: live FTDT duty-period card, logout in 0.920 s, DAL home rendered with no outgoing UAL home text. |
| DAL → UAL isolation | Passed: outgoing menu, favorites and document baselines established; incoming UAL menu/favorites/documents present and DAL entries absent. Native cookie check request 213 proved a stored cookie; request 310 after logout/login proved it absent. The fixture's fixed cookie label is UAL even when set during the DAL session. |
| MEC theme / feed recovery | Passed: outgoing UAL brand #12233e, ALPA placeholder, then DAL #002a50; five captured states, no retained UAL brand. Delayed DAL site/theme responses recovered visible MEC content. |
| Document catalogue / viewer | Passed: request 343 returned HTTP 200 after 29.009 s. The synthetic PDF downloaded and visibly rendered through the Blazor PDF canvas (824 × 1066 backing pixels), with no Blazor error. |
| Expired-session resume | Passed: one silent successful refresh (request 537), authenticated DAL home, no sign-in prompt. Installed package proof checked before resume. |
| Locked refresh | Passed: one Login Issue native alert, request 648; credential-presence probes were positive before and both absent after. Only presence booleans were recorded. |
| Rejected refresh | Passed: one Session Expired native alert, request 769; both stored credential entries removed. Installed package proof checked before resume. |
| FTDT | Sync/live card and responsive tabs passed; the duplicate-error-report assertion remains unverified in this Android run. |
Two automation attempts were invalid and were not counted as product failures or passes: a favorites tap was sent during the native browser's close transition (the route remained Home); after the native screenshot proved Home was visible, a real tap opened Favorites and passed. The locked-account help action opened Chrome's first-run screen over ALPA; that obscured the next login attempt. Chrome was stopped only on this owned emulator, ALPA's native foreground was verified, and the rejected-session test then ran successfully. No Chrome account was added or terms accepted.
A read-only remote check found target 2887cfb4a20c3fc4f8d2d02f4bb06cf68003db32, ahead of the already merged target 883339121ad38552980e559b10c257d0bf208c42:
git merge-tree --write-tree HEAD 2887cfb4 reports modify/delete conflicts in ALPAMobile/Services/DataManager.cs and UnitTest/DataManager_PrefetchDocumentsTests.cs. The preview did not alter the working tree or merge the target. These are new logic-porting conflicts, beyond the anticipated namespace reconciliation; further acceptance and final PR creation stopped rather than inventing a service-layer resolution.
Recommended reconciliation: compare and port PR 2537's behavior into DocumentPrefetchService (budget backfill), DocumentCacheService (download coalescing), and DocumentCatalogHydrator / catalogue projections (completion notification and tag-only category handling), preserving member-generation/cancellation boundaries. Adapt its tests to the existing service tests, retain the incoming presentation changes, and record each resolution. Restore neither the deleted DataManager nor its obsolete tests wholesale. Validate the reconciled tip before resuming device acceptance.
Still unverified on Android: interrupted sign-in after logout; the stalled-request 15-second attempt / 60-second total envelope; slow/offline logout with pending-request cancellation and anonymous push; FTDT duplicate-error-report behavior. The iOS results remain historical evidence, not a validation claim for a future reconciled candidate. No final integration PR or auto-complete was created.
The installed APK was pulled back and matched the --no-incremental Debug build. The embedded ALPADocs.dll matched at ELF offset 16,384, with source mtime 1790121811661383923 ns. Before each explicit launch/resume, the remote installed APK hash was checked against this proof.
| Artifact | SHA-256 |
|---|---|
Installed APK |
a4de350abad7190c85101dcbeb04cd9efcfb8dd18aba2b1ae8aad9b3cbcaf7c9 |
Embedded ALPADocs.dll |
37bba2df89ce6c11749fe389e0fb715f61ba4bd154a98dfde4d319249f36f904 |
acceptance-summary.json |
56eda937aa30f154409afbe66df970b314c781dfd1ed51ac7ffe145d5d128019 |
crash-verification-results.json |
2bd6fa66058f31a15bccd3ceb9c9cf4bb51bde99000b0670c213a282fa043138 |
isolation-results.json |
907f90da3359a324b016da17e323cf7472b01af665137e23f063e9334277fb86 |
delayed-catalogue-result.json |
93fc58d115489dae6f400f33da85fdb38c33a8038aee7bd37b135f4370f7ca5b |
theme-recovery-result.json |
7870a3ac12b5487f30619ed445ba01776a763edea919d19044fddbe2471a584a |
expired-session-result.json |
31ded56f58153827cc631915c168c9605f560e35a87e4b7650977ea278539288 |
locked-session-result.json |
b16e051ea278aedf151da8db73f08d250195c27865727a4e995b6b60dafa739e |
rejected-session-result.json |
5d5d3ad37bdb4a509d0527ff836cf272a6c867954e14ec43785e8026b3d4f5a0 |
target-drift-merge-preview.txt |
84eceb4fa63d1f0a07ea4686ba4c70fa44a9fbf60efc38dccb3a41386ac6c284 |
sentry-jni-replay-record-docs.trx |
28ec5ab4fd522350f9a97ba70460b802076cc14dec472cc8ea2e2421f8518a0f |
The acceptance-record update passed all 4 DocsTests.
Full logs, screenshots, native trees, fixture request timings, scripts and hashes are under /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance15/. The owned emulator/AVD, fixture, logcat and private ADB server were deleted; their process exits were verified. Protected worktrees and the shared ADB server were untouched.
Application correction: c323ac801f9d522c995c6a124384ca38d01e1e14.
Run 14 used display correction b29b0f9d51fa1266b6dd668c156f605c101fcf05 (docs-only tip 8fe15267fc81a2dce8b5e755584ee94772c9e351). Initial locked/rejected sign-in, UAL home and the Blazor FTDT LIVE duty-period card passed. After UAL logout, DAL sign-in crashed before DAL home appeared. The first JNI error was at 2026-09-22T23:42:50.476Z; SIGABRT followed at 23:42:51.289Z. PID 4922's .NET worker 5513 tried to delete stale JNI global reference 0x12fb2 in DeleteGlobalRef. Acceptance stopped. This disproves the earlier claim that the display fix alone cleared all post-login native crashes.
Reference traces show Sentry failed-HTTP-request enrichment calling MAUI battery reads. MAUI 10.0.60 disposes the sticky battery Intent on each read. Sentry 6.0.0 serializes its display/idiom reads but leaves battery reads concurrent.
On the dedicated API-36 device, a separate diagnostic package reproduced deleted-reference aborts with concurrent battery reads and with the actual Sentry MAUI processor. The SDK baseline also reported Intent.getIntExtra against a deleted/null reference. The production wrapper completed 16,000 calls across eight threads, asserting battery metadata and the MAUI SDK identity were retained on every call. The diagnostic process sent no events or member credentials. The run-14 tombstone has no managed owner stack; its specific stale handle cannot be mapped retrospectively, so the native reproduction and app replay are recorded separately.
The head composition applies an Android-only options post-configuration that decorates the existing SDK MAUI processor with a process-wide metadata lock. Event filtering, metadata, other processors and reporting remain enabled. The SDK processor type is internal, so the adapter uses its runtime type with Sentry's public generic removal API, without modifying private fields. A test against the installed SDK verifies replacement and idempotence; review this compatibility assumption when upgrading Sentry. iOS registration is unchanged.
The four regression tests cover concurrent calls across instances, retained/replaced/dropped events, exception recovery and actual SDK processor replacement. Before correction, 2 failed / 2 passed (255 overlapping calls, unsafe SDK processor retained); afterward, 4 passed / 0 failed. Manual review checked option-configuration order, process-wide locking, exception release, preserved SDK behavior, and Android-only registration. No independent human approval is claimed.
Run-14 logs, tombstone, launcher screenshot, installed-build proof and failed walkthrough record are under /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance14/. That run's owned emulator/AVD, fixture, private ADB and logcat processes were deleted and exit-verified. Native diagnostic source, APK proofs, baseline/corrected logs and results are under /private/tmp/AB2081-jni-investigation/; the diagnostic imports the production wrapper source directly. sentry-evidence-hashes.json records their SHA-256s.
| Evidence | SHA-256 |
|---|---|
sdk-probe-logcat.log |
c45b8031bd147298d206d5f237d5e98154f73617dfb7b5229ab7cccceb60328b |
guarded-probe-logcat.log |
bfef94e4fc660bb15753d7a045cf2c8be7ef8514d093f2ef0b590ab8b64c2e01 |
guarded-probe-result.json |
d7c4725b54629cac3387fbc3a75a84dea137e0a04bbc34562ff2efc1bc453bbb |
sentry-jni-red.trx |
ef494ef09c158ab63c73d4ce09acf89371d7ce7056a8011c814b4acfad6e1dc1 |
sentry-jni-green.trx |
1965083d62b667a65fbb0df1f48fb5f8f9cba32bb3e1c8521fcb70903e419cae |
Debug 2,943 / Release 2,927 / Docs 4, all passed with zero failed/skipped. The normal code-commit hook also passed 2,943 tests with no bypasses.
| Build | Result | Elapsed |
|---|---|---|
| ios-debug | 0 errors / 676 warnings | 00:00:11.69 |
| android-debug | 0 errors / 702 warnings | 00:03:04.25 |
| ios-release | 0 errors / 653 warnings | 00:00:16.04 |
| android-release | 0 errors / 679 warnings | 00:01:36.47 |
Navigation generation is current; gateway catalog 75 routes / 0 gaps and its regression script passed. Full logs and command records are under /private/tmp/AB2081-jni-investigation/sentry-validation/. Android Debug was built with --no-incremental -p:EmbedAssembliesIntoApk=true before the code commit; its reviewed source is identical to that commit. The installed package and embedded DLL are checked before launch.
| TRX | SHA-256 |
|---|---|
sentry-jni-debug.trx |
b4e7cd56cea8a4ee6d47b7697d13e0a8bc96810a406a34ce6f56826e82f62508 |
sentry-jni-release.trx |
b9b9c70b185ba7b6721ecfd8c305872cb392e7440dd11978bc1516d9e0f8cd04 |
sentry-jni-docs.trx |
d03cc19f96f4b55527f50148acd25a21d4c2034007a42987b3bd2c6cc810661d |
Device acceptance remains open. Run 15 is a fresh committed-candidate replay of the post-login failure; no successful walkthrough or final PR approval is claimed yet.
Application correction: b29b0f9d51fa1266b6dd668c156f605c101fcf05. This corrects the reproduced display race. Run 14 exposed a second native race during post-login loading; see the newer battery-race record above. Android acceptance remains open.
Run 13 retained JNI global-reference creation/deletion stacks from the exact run-12 APK. They show both ALPA log-event creation and background Sentry event enrichment entering MAUI display reads and disposing WindowManager proxies. Ordinary sign-in replay with verbose reference tracing did not reproduce the abort; a focused concurrent-read probe did.
On the dedicated API-36 emulator, eight workers reading the original DeviceDisplay.MainDisplayInfo reproduced SIGABRT / deleted JNI global reference / GetObjectClass at 2026-09-22T23:21:12Z (PID 6293). This matches the run-12 native failure signature. The original run-12 tombstone itself has no managed method or reference-owner identity, so its individual deleted handle cannot be symbolicated retrospectively.
MAUI 10.0.60's reader disposes a shared window-service proxy on every read. Sentry 6.0.0 locks its own display reads, which does not serialize ALPA's UI-thread logging against them. A managed exception handler cannot recover from ART's native abort.
The existing head display adapter now reads Android display metadata through DisplayManager, retaining borrowed service/display wrappers and disposing only the DisplayMetrics object it allocates. Logging takes one snapshot per event; the adapter and Jumpseat sizing use the same reader. iOS retains its MAUI reader. No SDK version, Sentry reporting policy, service-layer behavior, or TLS validation was changed.
The corrected native probe completed 16,000 ALPA reads across eight workers concurrently with 2,000 original MAUI reads on a ninth worker. All 18,000 reads checked 1080 × 2424, density 2.625, portrait; all nine workers passed and the app remained alive (PID 6566). The instrumented builds used --no-incremental, had 702 warnings / 0 errors, and had installed APK / embedded DLL hashes verified before launch. Diagnostic intent handling was removed before the application commit; it is absent from the acceptance candidate.
The regression source guard failed against all four unsafe app reads before correction. Its committed Debug and Release cases prohibit reintroducing that API on Android. The normal code-commit hook passed 2,939 tests without bypasses. Manual review checked native ownership, all head display callers, unchanged dimension/orientation semantics, and removal of temporary instrumentation. No independent human approval is claimed.
Debug 2,939 / Release 2,923 / Docs 4, all passed with zero failed/skipped. These counts include both Android source-guard cases; the host suite does not execute ART/JNI.
| Build | Result | Elapsed |
|---|---|---|
| ios-debug | 0 errors / 650 warnings | 9.66 s |
| android-debug | 0 errors / 702 warnings | 203.86 s |
| ios-release | 0 errors / 653 warnings | 17.83 s |
| android-release | 0 errors / 679 warnings | 89.7 s |
Navigation generation is current; the gateway catalog remains 75 routes / 0 gaps. The gateway regression script passed. Commands are recorded in /private/tmp/AB2081-jni-investigation/matrix.json; they follow the reproduction matrix below, with unique TRXs and --no-incremental -p:EmbedAssembliesIntoApk=true for the Android Debug acceptance package. Full logs were preserved and each matrix command returned zero.
| TRX | SHA-256 |
|---|---|
jni-fix-final-debug.trx |
f3e5133ae06c6ff789073b35a268ea57b65037945cfdd3ba1a45318212cdb389 |
jni-fix-release.trx |
d051f2dbf15566bd8628157cca62d9d342257cc58ee1a08a65d4c8bd3c6c58d9 |
jni-fix-docs.trx |
bd3a582f709ac26f3457ed01a3ca35cdf32800777c3c31981b757db02e4793ed |
Reference traces, APK/DLL provenance, original and corrected probe patches, native abort logs, nine-worker results, and a hash manifest are preserved under /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance13/. Build/test logs, exact-version upstream sources and the corrected probe injection are under /private/tmp/AB2081-jni-investigation/.
For a diagnostic reproduction only, use an isolated checkout and disposable API-36 device: apply run 13's probe.patch to ec324a19 for the failing case. For the correction, use b29b0f9d and temporarily insert fixed-probe-injection.txt after base.OnNewIntent(intent). Build/install with the recorded commands and verify the installed APK/DLL before launching; then send the ab2081-display-probe=true intent extra to the existing activity. The baseline aborts; the corrected probe must emit nine PASS records and retain its process. These patches are diagnostics, not a production feature or an acceptance substitute.
| Evidence | SHA-256 |
|---|---|
probe-native-crash.txt |
62833d921c768869558ab69e809b4bed84e2a6ee31ab2878e5ff45c5f0a704b4 |
fixed-probe-results.log |
c886f2c1caa623fd2ae1580ca90fb41c97234b0044ec0e47392d70cca1f8bf79 |
final-grefs.txt.gz |
0b7677d7e63b71ed2169e100b807236f11bb00e7cb5e018a430b7dd9b7bf122d |
Run 13's owned emulator/AVD, fixture, logcat and private ADB server were removed and their process exits verified. Final integration PR creation remains gated on remaining device acceptance. A fresh committed-candidate Blazor replay follows this validation record.
Tested and pushed revision d2138bea41b17a8f3054d5f7ec205c9c5748e9f7 fixes only the Python acceptance fixture and its tests. Application code remains at correction 9089afb364b69ba670a320241e69d1fee4473203.
The pre-fix regression reproduced starvation on both HTTPS listeners (two healthy-client handshake timeouts) and blocked shutdown (one failed assertion). All eight existing tests remained green. TLS negotiation now occurs in a dispatched request worker with a five-second handshake timeout; the listener accepts raw TCP immediately. After negotiation, the timeout is cleared so delayed HTTP acceptance scenarios retain their own timing.
13 fixture tests passed, including concurrent healthy/idle clients on both listeners, idle-handshake expiry, malformed TLS, prompt shutdown, and an HTTP body sent after the handshake timeout interval. Manual review checked socket ownership/cleanup on handshake failure and restoration of normal HTTP timing. No certificate-validation bypass was added. The full Debug unit/architecture suite passed 2,937 / 0 failed / 0 skipped; fixture-tls-regression.trx SHA-256: 6235bd87c675f7e3acfb228e12e775e8f01d8e6e88f540f853d2b0c67374405b. The fixture commit ran the normal pre-commit hook without bypasses.
Documentation verification: 4 passed / 0 failed / 0 skipped from DocsTests/DocsTests.csproj; android-acceptance12-docs.trx SHA-256: 1677506d13c5b3b11d2d6e90ff95def739a2d6cd3e949c4b98e62a99bc7cd0ac. The legacy hook's empty UnitTest Docs filter is not counted.
Dedicated Pixel 9 / API 36 Google APIs emulator AB2081-ServiceLayerIntegration01-AndroidAcceptance12, emulator-5590, WebView 133.0.6943.137. An owned ADB server listened only on 127.0.0.1:58744; the shared desktop server was untouched. The Debug build used --no-incremental -p:EmbedAssembliesIntoApk=true and passed with 702 warnings / 0 errors, 187.76 s. An initial ADB incremental installation could not be verified by APK pull-back; before any launch it was replaced with a full installation using --no-incremental --no-streaming. The pulled APK then matched the build byte for byte. Its embedded ALPADocs.dll matched the rebuilt DLL at ELF offset 16,384; source DLL mtime was 1790112280449435620 ns. The installed APK hash was checked again immediately before launch. The local fixture certificate was trusted only in this disposable device, retaining original roots and normal app TLS validation.
| Check | Result |
|---|---|
| Initial locked / rejected Blazor sign-in | Passed. Requests 32 / 37 each returned one HTTP 401; one corresponding inline error, no Blazor error. Native screenshots/XML preserved. |
| Successful Blazor sign-in | UAL home visibly rendered after request 39 returned HTTP 200. The post-login HTTP burst and ADB remained responsive. This observation is limited by the later process abort below. |
| FTDT import with cold airports | One duty period imported: Patched(0) Inserted(1) Deleted(0) Skipped(0). Airport requests 54 / 81 / 83 returned the controlled HTTP 503. FTDT screen responsiveness was not tested before the abort. |
| Continued Android acceptance | Stopped / incomplete after a native app abort. Account isolation, interrupted login, refresh/expiry, slow logout/push, delayed documents/viewer and FTDT UI checks remain unverified on Android. |
At 21:29:46.033 UTC, Android reported JNI DETECTED ERROR IN APPLICATION: jobject is an invalid global reference (deleted reference, index 1692), in GetObjectClass on a .NET TP Worker. At 21:29:46.424 UTC the app process received SIGABRT. The stack contains ART CheckJNI and Mono runtime frames; it does not identify an application method. The process exited to the Android launcher before the next FTDT navigation command. Post-login background requests, including controlled airport failures and unconfigured catalogue routes returning 501, preceded the abort. That timing does not establish which operation owns the invalid JNI reference or whether the defect is in app, instrumentation, or runtime code. No FTDT freeze recurrence is claimed.
After the crash, the fixture health endpoint still returned HTTP 200 with normal TLS validation and the private ADB server still listed the device immediately. Thus the run 11 fixture/ADB stall did not recur. Acceptance stopped per the runbook; there was no relaunch, application patch, or retry past the native failure. Next work is to isolate the invalid JNI reference during post-login background work and review a correction before resuming. The final integration PR remains gated by incomplete Android acceptance.
Evidence, scripts, full logs, native tombstone, screenshots and SHA-256 manifest are in /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance12/. The owned emulator/AVD, fixture, logcat reader and private ADB server were removed; process termination was independently verified.
| Artifact | SHA-256 |
|---|---|
| Installed APK | 8b1fb82ee466eecd13ba7b964fc55734681e6bdf720ea7040218a5c50889b693 |
Embedded ALPADocs.dll |
9bf9698f372e341b8d07ce7f76c1def8f30b193c928cbe61783ed2fc7bc8c56b |
| Pre-fix fixture regression log | 1c5c184483136bcf4fb8206189255f9b746f24f8285dd07274abec01d10498b2 |
| Passing fixture regression log | 76455b20f3aabbdc8130fe33a7fe3a0a531ed501cbdcf4d023c4dc56b94d9997 |
| Native crash buffer | 104979559421793c606ab29f9f4db14c5067f4e0b49f315688e7e7f8a44399d6 |
| Native tombstone | 86fdfb5990f807a7cf82ca520862d371409bb3b9f364f93efa6296a4a0b47a11 |
| Visible signed-in UAL home | 88d916bc27b799020178fac9cbf7d9bac6611f4048d6213993ad9717fb40c7a5 |
| Launcher after app crash | b313ec18d15e0a4564ddaa3cc0c7bfd3870f91badaa7f8c52dee25f6aaea8e50 |
The iOS completion below was committed first as 2706eafceb60302b5292b7ca5424e9242d459d20. A fresh Android run then used that documentation tip and unchanged application correction 9089afb364b69ba670a320241e69d1fee4473203. Per the stop rule, this run stopped at the infrastructure failure below; no application or fixture code was patched to retry it.
Dedicated emulator: AB2081-ServiceLayerIntegration01-AndroidAcceptance11, Pixel 9, API 36 Google APIs, emulator-5560. Android System WebView 133.0.6943.137 rendered the Blazor application successfully, resolving run 09's obsolete-WebView startup blocker. The self-contained Debug build used --no-incremental -p:EmbedAssembliesIntoApk=true: 702 warnings, 0 errors, 187.60 s. The installed APK was pulled back and matched byte for byte, and the embedded DLL matched the rebuilt DLL at ELF payload offset 16,384. The APK hash was checked again immediately before launch.
The local fixture CA was added only to this disposable emulator's Conscrypt trust store, retaining the original roots and app certificate validation. The Zygote mount namespace was verified before app launch. Initial HTTPS fixture requests returned HTTP 200.
| Check | Result |
|---|---|
| Blazor startup / native notification permission | Passed. Visible anonymous Blazor home; real Allow tap. A native registration reached the mock endpoint with HTTP 200. This is not post-logout push evidence. |
| Initially locked credentials | Passed. One POST (request 44), HTTP 401, one visible inline message advising account unlock/password reset. No native dialog or Blazor error. |
| Initially rejected credentials | Passed. One POST (request 49), HTTP 401, one visible invalid-credentials message. |
| First successful sign-in / later walkthroughs | Not verified. Auth request 54 returned HTTP 200; the debug bridge and reverse-forwarded HTTP traffic then stalled before the signed-in home could be verified. No FTDT navigation, account isolation, logout, expiry, interrupted sign-in or document-viewer pass is claimed for Android. |
Even host-level adb devices timed out after 8 seconds, so the missing bridge response cannot establish an app freeze. A three-second read-only sample of the existing shared ADB server (PID 3642) places its main event loop in handle_packet → service_to_fd → socket_spec_connect → network_loopback_client → __connect. Its sockets show six established connections to fixture port 56572 and another SYN_SENT connection. The app and fixture logs stop at the same sign-in prefetch burst.
The fixture wraps its listening socket with TLS before ThreadingHTTPServer dispatches accepted requests. That accept-time handshake plus the backed-up reverse-connection queue is the suspected cause; it requires a focused fixture regression to prove the mechanism. Stopping only this run's mock server restored adb devices immediately, without restarting the shared ADB server. A diagnostic screenshot taken after that stop showed the signed-in UAL Blazor home. It is not a completed acceptance walkthrough or proof of its timing before the fixture stopped. No app crash or FTDT regression was established.
Recommended next work: reproduce the accept/handshake stall in the fixture, move TLS handshakes into bounded worker handling with a handshake timeout, and add a concurrent-client regression. Then resume Android on a fresh emulator, preferably with an isolated ADB server. Do not change service-layer behavior to compensate for this test infrastructure failure.
The owned emulator/AVD, mock server, log readers and blocked diagnostic client were removed; process termination was independently verified. The shared ADB server was left running. Evidence, scripts, screenshots, logs and hash manifest: /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance11/.
| Artifact | SHA-256 |
|---|---|
| Installed APK | e684d0d53f1f1410b6be69cc1516ce4a27cee51a0480e8f82afd61aa7c41c30e |
Embedded ALPADocs.dll |
d9ca365245bbab5ea5c6d62efa8f9790e81ab9e0cb41ff724aaac3fbcc6b9912 |
adb-server-sample.txt |
6eb4ea02e87efa6368ee0fb3481206b0a6a13e7c09ffebfcad5a29cc5b8d998a |
adb-sockets.txt |
5694f2a40a3346735b66ce10cd941c3f5dd3492a24e88f795c66273b71d43640 |
adb-after-fixture-stop.txt |
439917f3fb0acdd0b46d5399817f193fe97e4f5729ff6a16e4d2072729764510 |
Documentation verification on 2706eafc: 4 passed, 0 failed, 0 skipped from DocsTests/DocsTests.csproj; TRX SHA-256 183b31246638ce46e50ca4c7af6dd4225b120277982c2f42b14d91e7e4b7d6e3. The legacy hook's UnitTest Docs-category filter selects zero tests and is not counted as that result. Both logs/TRXs are preserved in the iOS run 10 evidence directory. The final integration PR remains gated by unfinished Android acceptance.
Per the iOS-first acceptance order, the remaining isolation, theme/recovery and anonymous push checks ran on revision 5aa435f6b8fb4d4b40c73824de27c1f34330898a, application correction 9089afb364b69ba670a320241e69d1fee4473203. No application code changed. The dedicated iPhone 15 Pro / iOS 26.5 simulator was AB2081-ServiceLayerIntegration01-MockAcceptance10 (5F433A88-1F56-47FB-A372-8DC89299266A). The normal signed Debug build used --no-incremental: 676 warnings, 0 errors, 19.98 s. DLL/executable SHA-256 and nanosecond mtime matched the installed bundle before launch; strict signature verification passed. Provenance was checked again before each relaunch.
All authentication used the local HTTPS fixture's synthetic UAL/DAL identities through the Blazor login and profile/logout controls. The web-cookie probe used the app's native web viewer, opened by a real tap in the Blazor drawer. No real member data was seeded.
| Check | Result and evidence |
|---|---|
| Menu isolation | UAL ACCEPTANCE MENU visibly present before logout; DAL ACCEPTANCE MENU replaced it after DAL login and a five-second menu response delay. No UAL row remained. |
| Favorites isolation | UAL ACCEPTANCE FAVORITE visibly present before logout; DAL ACCEPTANCE FAVORITE only after DAL login. The fixtures reuse the favorite/menu ids to expose retained cached identity. |
| Document isolation | UAL ACCEPTANCE DOCUMENT visibly present in the UAL category; DAL ACCEPTANCE DOCUMENT only in the DAL category after switching. |
| Web-cookie isolation | The local viewer set a UAL cookie, then a separate request and visible page proved PRESENT. Opening only the check page after DAL login proved ABSENT. Server probe sequences 258 and 361 independently confirm present then absent. |
| Home/feed recovery | Six distinct animation-frame states captured anonymous home, login, signing in, empty incoming home and the DAL feed. Zero states contained UAL text; no Blazor error appeared. |
| MEC theme recovery | UAL baseline brand/accent #12233e / #f7bb0d. Delayed DAL site/theme responses produced an empty incoming MEC page with the ALPA placeholder theme, then DAL brand/accent #002a50 / #c01933 and DAL content. Four distinct captured states; zero UAL theme states. No claim about the separately filed late GLOBAL-theme race (AB#2859). |
| Native push prerequisite | Debug skips the startup permission prompt. On the synthetic anonymous device, a fixture flight audience exposed the existing Blazor notification test page. Its real local-notification control requested permission; a native Allow tap produced NotificationPermission Authorized and Push token received. No APNS token or installation id was injected. |
| Slow logout and anonymous push | With an actual signed-in registration (request 748, HTTP 200), document request 734 was held by the fixture's 60-second delay. Logout began 2.796 s into that request and completed in 0.656 s. The server recorded cancellation after logout began, followed by anonymous registration request 772: HTTP 200, authorization absent. The app logged registration completion. |
The first push observation also proved anonymous registration, but its document request had already reached the 30-second timeout before logout; that observation is preserved separately and is not counted as the slow-logout result. The final observation above requires the request to remain within its deadline at logout and correlates its later cancellation. Actual offline logout was not separately exercised: the runbook's slow or offline alternative is satisfied by the pending-request case. This checks registration, not remote push delivery. The earlier iOS run 07 covers interrupted sign-in, rejected/locked credentials, expired-session resume, document download/open and native cancellation/redirect; run 08 covers corrected FTDT. No-logout account switching remains N/A per the user. Android acceptance remains outstanding.
Installed DLL SHA-256: 58cbbd64d167c691e0f395ba55d5cb91e5eaca853ddc8dd363f8ef42ea4b5701; source/installed mtime: 1790108869598426464 ns. Executable SHA-256: 15032f9b35c4d9ad2d3fec095f56feb2de9f5c5ec162a88529e5ca7063fb29d1.
| Evidence file | SHA-256 |
|---|---|
switch-visible-frames.json |
1f150a11e5a5d4b7bb8b72580d1c393f7abbb78bd707a6d1c833ef799464598a |
cookie-isolation-result.json |
8b1fe91864e3f8ed924a9e1bab5488d5627a6f638ba14d10b9b0b44cb77de048 |
dal-theme-transition.json |
7ea0f50b9c149347dcdd438f2cf24165dc1d6df604aa941055651ca16ca92a92 |
slow-logout-push-result.json |
cc6c8d24c47114993d31c8657569eac70a9b904aebf181844ee46949ffbb8661 |
Screenshots, native accessibility/CDP captures, server/app logs, fixture scripts and complete SHA-256 manifest are in /private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance10/. Fixture preparation corrected missing blazor-hybrid menu metadata; unknown ancillary routes remain explicit HTTP 501 fixture gaps and are not claimed as successful service checks. The simulator was shut down and deleted; all owned server, Appium and log processes were independently verified stopped. No final PR or auto-complete was created.
Acceptance resumed after review and the green matrix on branch revision 66b7af649afb9923657c4738ddd5a68012c644bb, application correction 9089afb364b69ba670a320241e69d1fee4473203. The FTDT regression and correction review are recorded in the next section.
Dedicated simulator AB2081-ServiceLayerIntegration01-MockAcceptance08 (3F9BBC12-3AD4-4DBD-9F9B-F6732581A9F2), iPhone 15 Pro / iOS 26.5. The normal signed Debug build used --no-incremental and completed with 676 warnings / 0 errors in 20.62 s. Before launch, strict signature verification and source/installed SHA-256 and nanosecond mtime comparisons passed for the DLL and executable. All sign-ins used the local HTTPS fixture's synthetic accounts through the Blazor login form.
| Walkthrough | Result | Evidence |
|---|---|---|
| FTDT import with unavailable airport metadata | Passed | Airport warm-up received three controlled HTTP 503 responses. FTDT independently imported one valid duty period: Patched(0) Inserted(1) Deleted(0) Skipped(0), then synchronization complete. |
| Cold-cache FTDT page | Passed | /ftdt/dashboard?tab=dp rendered the imported one-hour duty period; navigation plus screenshot/state capture took 0.975 s, no Blazor error or native alert. |
| Cold-cache UI responsiveness | Passed | Three real Appium taps expanded details, selected Cumulative Limitations and returned to Duty Periods. 190 animation frames; maximum frame gap 33 ms. No synthetic DOM click was used. |
| FTDT sync failure reporting | Passed | Controlled FTDT 503 on the next supported logout/login flow: exactly three HTTP attempts and one native System.Exception report for GetDutyPeriodsUpdatedAtAsync. No duplicate outer-layer error report, dialog or frozen page. |
| FTDT recovery with warm airports | Passed | Restored HTTP 200 airport baseline and FTDT record; supported logout/login resynchronized and rendered the duty period. A real tap opened the Blazor edit page without error. |
Installed ALPADocs.dll SHA-256: 1bb1e05d1ed9b2fb84cc737df75e35ca9dd1388a702366d58134d941f55fb027; source and installed mtime: 1790107371300162488 ns. Visible cold-cache screenshot SHA-256: d9891a5798b665a5c30cdd96a2bd4c0f11655938cf517ce41ff958a9980b8e34. Error-event evidence SHA-256: a96f95b0031d9d86327c56d098cfac4d51a8cb06842365c8896f7c2e360be958.
Full screenshots, native/CDP state, request log, app log and hash manifest: /private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance08/. The simulator was shut down and deleted; its mock, Appium and log processes were independently verified stopped.
A dedicated Pixel 4 / API 30 Google APIs emulator was created as AB2081-ServiceLayerIntegration01-AndroidAcceptance09 (emulator-5560). Its self-contained Debug APK used --no-incremental -p:EmbedAssembliesIntoApk=true; 702 warnings / 0 errors, 169.16 s. The installed APK was pulled back and matched the built APK byte for byte before launch. The provenance check initially expected loose DLL entries; inspection identified .NET's ELF-wrapped lib/arm64-v8a/lib_ALPADocs.dll.so. Its payload at offset 16,384 exactly matched the rebuilt DLL; source mtime and package timestamp/hash were recorded before launch. No application or certificate-validation bypass was introduced for this packaging check.
The selected API 30 image ships Android System WebView 91.0.4472.114. Startup logcat shows Uncaught SyntaxError: Unexpected token '{' in _framework/blazor.webview.js, followed by Blazor is not defined. The visible app remains on its loading placeholder; its native process and debug HTTP server are alive, but CDP is not ready. This is a failed acceptance setup, not evidence that the FTDT correction regressed Android. No Android walkthrough ran. Per the stop rule, no application patch or repeated launch was attempted.
Next Android run must use a fresh image with a current supported WebView (the installed API 36 image is available), reestablish normal local-fixture certificate trust, and verify the installed candidate before launch. Do not count the API 30 attempt as Android acceptance.
Installed APK SHA-256: 73f97063aaf364dc5b5bcd29de610a67dae59b62f3a45d1a68b9c7d8830d0f92. Android final screenshot SHA-256: d883a05e92c62ade29e351ab736cd7191196b7f722ddcedf52accc412d7a1ac5. Startup logcat SHA-256: fc032c278767ee891ea238730dabff69b1ad84f26fccf0352cf78a294136e665. Evidence: /private/tmp/AB2081-ServiceLayerIntegration01-android-acceptance09/. The owned emulator, AVD and mock server were removed and their termination verified.
Overall acceptance remains incomplete. Android, remaining member-data/cookie isolation, and anonymous push-registration evidence still gate the final integration PR. Earlier walkthrough evidence below is historical; no-logout switching remains N/A per the user. No final integration PR or auto-complete was created.
Application revision 9089afb364b69ba670a320241e69d1fee4473203. The user authorized isolating and correcting the FTDT freeze, reviewing the change, and then resuming acceptance. The bounded regression reproduced the blocking path before the fix: an incomplete airport request held FlightSearchAirportLookup.TryGet for the full two-second assertion window. The test releases the request in finally; the preserved red TRX reports one failure rather than leaving a hung test host. This confirms a blocking lookup, while the historical native sample still does not identify the precise managed continuation in the original device wait.
The correction adds a synchronous cache-only read to the existing IFlightSearchQueries port. The head lookup consumes the flight service's current-generation memory; it performs no authentication, persistence read or HTTP request. A cold cache follows the documented IAirportLookup absent-metadata behavior. Login warm-up remains asynchronous. Later calculations observe successful warm-up/refresh; they do not reuse a permanently empty or outgoing-member dictionary. The change does not automatically recalculate an already rendered page when warm-up finishes; ordinary subsequent calculation reads the newly available data.
Review checked the existing Application boundary, context lock/generation race, metadata mapping, null/city/code behavior, and absence of hidden background work. No blocking review finding remains. Six regressions cover cold nonblocking reads, no I/O, persisted metadata, failed-warm-up recovery, refresh and invalidation including late publication. All six pass; ten existing flight-service tests also pass. The synthetic HTTPS fixture now supplies a valid ATL airport baseline, with an explicit override for controlled failure/delay. Its eight tests pass. All code-commit hooks ran without bypass: architecture and 2,937 unit tests passed.
The reproduction commands below ran on that committed revision with unique TRX filenames. All tests passed with zero failures/skips. All four platform builds have zero errors. Nav is current; gateway catalogue is 75 routes / 0 gaps, and its regression passed.
| Check | Passed / total | TRX SHA-256 |
|---|---|---|
| Debug | 2937 / 2937 | 576b02961f228e1babfd4e7d2ca1b153510a6d83147f4363da5441e571255b75 |
| Release | 2921 / 2921 | 5782c12ece9b8739d243beb3fc2cd669e293b54696db87763b432444ef4b5ba4 |
| Docs | 4 / 4 | 415636b16f9bc8356c2c3edbe3f9051dc6acebdf2b5dbca6e5f2b0b338c59cc0 |
| Build | Warnings | Errors | Seconds |
|---|---|---|---|
| ios-debug | 650 | 0 | 7.22 |
| android-debug | 676 | 0 | 38.4 |
| ios-release | 653 | 0 | 15.19 |
| android-release | 679 | 0 | 78.63 |
Full commands, logs, TRX hashes and review regression evidence are retained in /private/tmp/AB2081-ftdt-freeze/. Matrix TRXs are named ftdt-freeze-matrix-{debug,release,docs}.trx.
Device acceptance resumes on a fresh dedicated Blazor simulator after this validation record is committed. The prior acceptance tables below are historical evidence, not passes on the corrected revision. Remaining Android/isolation/push/cookie gates still block the final PR.
Tested branch revision 3875fa5ded8861f5b81ef7a2aa20b488212489e5, with application code from e908d04ae8b228f43b824aafeb81691a248a9892. The full matrix above the historical records is green: 2,931 Debug / 2,915 Release / 4 Docs, four builds with zero errors, 75 gateway routes / 0 gaps. The mock endpoint has seven passing HTTPS fixture tests.
Acceptance is incomplete. FTDT imported one synthetic record, then the Blazor FTDT screen froze. Per the runbook, the run stopped; no service, transport or navigation fix was made. Android acceptance and the final integration PR were not started.
| Walkthrough | Result | Device evidence / limitation |
|---|---|---|
| Normal Blazor UAL logout → DAL login | Passed measured states | Real vault roles, separate normal-endpoint device. Logout click → first anonymous frame 366 ms; Appium call 0.504 s; final DAL home present, UAL absent; no Blazor error. This is not a new frame-by-frame DAL visibility claim. |
| Earlier 40-second logout observation | Unresolved historical observation | Did not recur. Current probe recorded 691 frames, maximum gap 175 ms. The earlier delay's cause is not established. |
| Initial rejected / locked Blazor sign-in | Passed | Synthetic identities only; one auth request for each tap, one corresponding inline error, no native dialog and no Blazor error. |
| Expired-session resume | Passed | One-minute synthetic session; app backgrounded past expiry, then one successful refresh; signed-in home retained, no dialog. Native log records refresh on attempt 1. |
| Default stalled socket / native iOS cancellation | Passed | PAC GET: three canceled attempts of 14.993 / 14.988 / 14.980 s; 51.171 s total, within the 15 s / 60 s policy. No native dialog or Blazor error. |
| Cross-host redirect bearer handling | Passed | Native iOS request to fixture PAC route carried Authorization; redirected request to the second local HTTPS host did not. Both requests are in the server log. |
| Locked refresh recovery | Passed | Exactly one native Login Issue dialog; anonymous home; both synthetic secure credential entries absent after recovery. |
| Rejected refresh recovery | Passed | Exactly one native Session Expired dialog; anonymous home. Both synthetic credential entries were positively observed present before the attempt and absent afterwards; values were not recorded. |
| Interrupted Blazor sign-in | Passed | Killed after the delayed synthetic auth POST began and before any response; server observed cancellation after 0.395 s. Installed hashes/mtimes rechecked before relaunch. Settled app showed anonymous Blazor home without error. |
| Logout while a document request stalls | Passed logout behavior | 0.642 s to anonymous home; no Blazor error. Native document requests honored their separate 30 s attempt limit. Actual airplane-mode/offline behavior remains unrun. |
| Anonymous push re-registration | Unverified | No device push-token registration evidence was captured; logout completion alone does not prove this gate. |
| Web-cookie cleanup | Unverified | The synthetic document.cookie probe could not establish a nonempty baseline; no cleanup result is inferred from its empty reading. |
| Delayed document catalogue and viewer | Passed | Catalogue responded after 29.004 s (app logged 29,080 ms), hydrated one document, and displayed it in Blazor. One authenticated download returned the synthetic PDF; its text rendered in the viewer. Optional automatic downloads were declined with a real tap. |
| FTDT synchronization and UI | Failed / stopped | Import logged Patched(0) Inserted(1) Deleted(0) Skipped(0), followed by synchronization complete. Navigating to /ftdt/dashboard?tab=dp left blank content and a blocked main thread. No FTDT UI or duplicate-error-reporting pass is claimed. |
| No-logout switching | N/A | User confirmed it is not a supported app flow. |
| Remaining isolation / recovery and Android | Not completed | Remaining menu/favorites/document/cookie isolation, applicable recovery cases and Android walkthroughs remain gated after the FTDT stop. |
The synthetic FTDT record was generated from the passing adapter test's Wire factory, then given current start/end timestamps, a synthetic member and a synthetic note. It was served through the real HTTP adapter, not inserted directly into a member database. At 19:40:46.832 UTC the importer logged one record; at 19:40:46.850 UTC it logged one insert and no skips. At 19:40:48.095 UTC, while entering the FTDT route, the last forward progress logs were GetCacheJSON / GetCache for GetFlightSearchAirportsAsync.
The fixture had not configured /api/FlightSearchV2/GetAirportAndCityCodes, so the earlier warm-up received its explicit 501 fixture-gap response. This missing airport baseline is a material setup limitation. The app then remained alive with a blank FTDT content area; CDP status timed out after five seconds. A five-second native process sample recorded all 4,172 main-thread samples waiting in System.Threading.Monitor / __psynch_cvwait.
ALPAMobile/Services/FlightSearchAirportLookup.cs:30 calls queries.GetAirportsAsync(false).GetAwaiter().GetResult() during cache construction. That is a plausible cold-cache deadlock trigger, consistent with the logs and native wait, not a confirmed managed stack attribution. Git blame traces the synchronous wait to bbe527426 (2026-06-22), before this integration; this run does not establish a new service-layer regression. No fix or retry past the freeze was attempted.
Next review should supply the missing airport fixture baseline and isolate the cold-cache failure path with a regression. If confirmed, airport acquisition should be asynchronous; the synchronous lookup should consume ready data without blocking the UI thread. Resume FTDT and the remaining platform gates only after the failure is reviewed and resolved.
Both dedicated iPhone 15 Pro / iOS 26.5 simulators ran normally signed iOS Debug builds with --no-incremental, 676 warnings and zero errors. Strict signature checks and source/installed DLL plus executable hashes and mtimes passed before launch. The interruption relaunch repeated the installed-artifact check. The mock opt-in was written only to its dedicated app container; its temporary HTTPS certificate was trusted only by that simulator. No vault credentials were entered on the mock device, and the mock never proxied traffic.
| Run | Simulator UDID | Installed ALPADocs.dll SHA-256 | Matched mtime (ns) |
|---|---|---|---|
| Normal endpoints, acceptance06 | 0645562F-9C49-407B-9109-3F17DD128791 |
f9633b3c8ed099b8fe4fc9c1a579546ae55374cd888fc8d898d5b7403418cb1b |
1790104591514472057 |
| Synthetic HTTPS, acceptance07 | 09343244-395E-402F-BB24-46C00378AF68 |
2407e3fd2cf559abede91084d39a9f823a350ff995a3bc75ff198bb814c24d27 |
1790104887525256394 |
Owned Appium sessions/servers, log streams and the mock server were stopped; both dedicated simulators were deleted. Process exit and simulator deletion were verified. Other agents' devices and the three protected worktrees were untouched.
Capture setup notes: initial native navigation was unnecessary because Blazor was already mounted; the locked-account help page opened a native browser overlay that had to be closed before another login; the first post-interruption CDP read preceded WebView readiness and was replaced by a settled capture. None of those setup observations is counted as a device pass.
Local evidence directories (not uploaded CI artifacts):
/private/tmp/AB2081-ServiceLayerIntegration01-blazor-acceptance06//private/tmp/AB2081-ServiceLayerIntegration01-mock-acceptance07/Each contains evidence-sha256.json, installed-build proof, screenshots and logs. Selected failure and acceptance artifact hashes:
| Evidence (acceptance07) | SHA-256 |
|---|---|
server/requests.jsonl |
9f149f41e7d87b66a483b86f626647e42f6a0537b3e896d0761c7afc33c5b3d0 |
ftdt-visible-screen.png |
1a7c04062e66f82e6da7404eb0fe9e6afdf95f4255285dad8ef827f6c7dd7d65 |
ftdt-unresponsive-process-sample.txt |
f32b7e28437663b839f015f4799ba91e9f5ce9c5358eabb6a0e2e260c38b0ca9 |
ftdt-cdp-status.log |
11234b936d01c5238b76da0f943a2a2e32e1e39696ef96d16d39561ca8d8cc64 |
stalled-pac-result.json |
96c8f20cdf2cb89b2596198a5ccacc91609620bb7b4f358afb274d4c3b468d0b |
cross-host-result.json |
2145183b0302045174de8510fbd1652fcb750360545758c6a8213b160f4dc69d |
locked-session-result.json |
ef28adf48ae61653a202c293f02b0326c1209c1543b307ad96b36fd41adb5000 |
rejected-session-result.json |
9133578ee967210abf71e006e812784ef2a1c954788b76e9c90e758f8e3b0516 |
interrupted-login-result.json |
5f984e91fc38f9e4eba2e44dc8a408b6b172dd905881f5b7a202fa06c87df157 |
delayed-catalogue-result.json |
3c43f27a3868227f8161a71fcc52f5356d2653fb1ead33e68be85309af093d77 |
fixture-document-open-visible.png |
a989bf5be152045f03b611c14e7f39a7d06d75380d05b92ac7c8b320476c219b |
teardown.log |
92e8926be675ea691ca7a077eb45729be600e6cd90bb1f994d05855a3d608847 |
The user requested a mock endpoint for locked/rejected credentials, session expiry, delayed responses and cross-host redirects. Candidate e908d04ae8b228f43b824aafeb81691a248a9892 adds a loopback HTTPS fixture and an opt-in mobile Debug endpoint override through the existing ApiEndpointOptionsConfigurator. All six configured origins change together. Release has no override; a regression test checks the type is absent. Normal Debug launches with no opt-in file retain existing endpoint selection. No authentication, logout or transport implementation was changed. The no-logout UI scenario is N/A by the user's scope decision.
Fixture evidence: 7 HTTPS tests passed, including exact locked/rejected response bodies, expiry lifetime, actual delay, client disconnect detection, separate redirect sink, credential refusal/redaction, and unknown-route reporting. These validate the fixture, not device behavior. The 11 focused Debug configuration tests passed; all commit hooks ran without bypass. Setup and controls: fixture README.
Full matrix on the committed candidate (0 failures/skips):
| Check | Result |
|---|---|
| debug | 2931 passed; acceptance-fixture-matrix-debug.trx; SHA-256 ac5c6c863de82eaf8570d499997aed311da5de46ff2f8ab0dcf02cd9a650b7f7 |
| release | 2915 passed; acceptance-fixture-matrix-release.trx; SHA-256 24c8c379ce40cb9699d6fd584de77f236005bf879ce0daa889b2d4080cabae05 |
| docs | 4 passed; acceptance-fixture-matrix-docs.trx; SHA-256 10d565e2ea3cbacbc6cabd7b41f39d040522bc8e6062abdd62257eb74ac57d27 |
| ios-debug | 0 errors, 650 warnings; 8.32 s |
| android-debug | 0 errors, 676 warnings; 40.96 s |
| ios-release | 0 errors, 653 warnings; 16.22 s |
| android-release | 0 errors, 679 warnings; 83.88 s |
| Navigation / gateway | Nav regions current; 75 routes, 0 gaps; catalogue regression 1 passed |
Full logs, command records and fixture test output are retained locally under /private/tmp/AB2081-acceptance-fixture/. Matrix iOS builds disabled signing only for compilation; device deployment must rebuild normally signed with --no-incremental and prove installed SHA-256/mtime before launch. Device acceptance remains pending below.
Tested revision: ea98fc62a2eeeeb337875d41ab5f0a065c1b3e99, with unchanged application and test sources from correction 6c729bb7f29a1143606eeb1faa3cc498302679fb. The user requested visibility verification through Blazor, then also requested no-logout verification. Those are separate results:
| Scenario | Result | Evidence / limit |
|---|---|---|
| UAL → Blazor Profile → Log Out → Blazor Login → DAL | Visibility passed for this recorded run | Razor login → skeleton with DAL navigation → DAL home; no retained UAL content during DAL sign-in |
| DAL sign-in frame samples | 338 callbacks; 0 UAL, 0 mixed-member, 0 Blazor errors | Includes login, skeleton, and rendered DAL states |
| After first anonymous-home frame through DAL home | 673 callbacks; 0 UAL | Full probe: 793 frame callbacks and 16 mutation samples; visible UAL baseline proved the probe records outgoing content |
| No-logout Blazor member switch | N/A — user confirmed | The app requires logout before signing in as another member; signed-in /login redirects to /alpa |
Created iPhone 15 Pro / iOS 26.5 simulator AB2081-ServiceLayerIntegration01-BlazorVisibility05, UDID 55D91888-8AA8-4096-87C8-C7D2A929417D. Normal signed iOS Debug build used --no-incremental, RuntimeIdentifier=iossimulator-arm64, MauiDevFlowPort=65036, -m:1, and -nr:false: 0 errors, 676 warnings, 20.93 seconds. Before its single launch, strict signature verification passed; both source/installed artifacts matched by SHA-256 and mtime:
| Artifact | SHA-256 | Source and installed mtime (ns) |
|---|---|---|
ALPADocs.dll |
f7917ef0a7dfbac2cc2bf9e67ca29d5830cf6927dee22d1a4e9efc3533aef368 |
1790100959043687260 |
ALPADocs |
351cc06d646b84f11bb694abac50d855648f761344b0109b45ee36df52347f72 |
1790100965682419259 |
UAL signed in through the actual Razor /login form using the approved vault role. After its home initialized, real Appium touches opened the Blazor Profile and activated its profile.logOutButton9. The anonymous home then opened the Razor login form, and a real login.membersLoginButton4 touch submitted DAL. No native LoginPage was invoked. The read-only DOM/frame probe remained in the same webview across this entire flow.
The logout recording contains 15 decoded frames over 40.887001 seconds. The real logout Appium call took 40.091 seconds to return. The outgoing Profile remained visible while the operation was pending, then gave way to a skeleton and anonymous home. One callback still contained outgoing Profile/navigation while the route had changed to /alpa, before the clear; it was not a DAL-session frame. The first anonymous-home callback was at 18:19:37.183 UTC; no later callback contained UAL. Sparse video and the callback gap do not establish smooth logout responsiveness or exact authentication-event timing. That delay is preserved as an observation, not retried away or asserted to be network latency.
The DAL sign-in recording contains 164 decoded frames over 4.204200 seconds. All frame contact sheets were inspected, along with the DOM trace. The first skeleton/DAL-navigation callback arrived at 18:19:43.819 UTC, followed by DAL home at 18:19:46.667 UTC. No UAL pixels were observed in the recorded DAL transition, and no Blazor error indicator was visible. These are measured results for this run, not a guarantee for every scheduling condition or a substitute for cookie, favorites, document-isolation, or Android acceptance. Credential fields and the Profile member number were masked in the videos before inspection; private unredacted recordings were deleted.
On the same signed-in DAL candidate, Blazor.navigateTo('/login') was used only to check the existing route guard. Before and after: /alpa, DAL present, no login form. No logout or credential submission occurred in this guard check. Source inspection finds the existing LoginModal/ILoginModalPresenter.Open() components, but no current signed-in UI trigger.
The user subsequently confirmed no-logout switching is not applicable to this app. The gate is N/A, not a pass. No route bypass or artificial account-switch trigger is required. The supported acceptance flow is Blazor Profile logout followed by Blazor login; interrupted sign-in after logout remains applicable.
Only this run's Appium session/server and dedicated simulator were removed; server exit and simulator deletion were verified. Local evidence directory: /private/tmp/AB2081-ServiceLayerIntegration01-blazor-visibility05/. Full frame timestamps, probe source/trace, decoded frames/contact sheets, redacted videos, installed-build proof, logs, and selected-file SHA-256 manifest are retained. No application/test source changed. Automated correction counts remain 2,920 / 2,914 / 4, all four matrix builds with zero errors, and 75 gateway routes / 0 gaps. The final PR remains gated on incomplete acceptance.
| Evidence | SHA-256 |
|---|---|
ios-installed-build.json |
3e481438664abb3f7337f7c4af7d40f5930ef6615fe49a20df2cb0b4447118f2 |
visibility-trace.json |
0463bf19c63f34637a466af9b2cf8ddc9deb6e0b2f042fb17cff91bfeaae4865 |
blazor-logout-redacted.mp4 |
4521f1a9fdf341966e76e6f1e3f030d00893df8d125ba109e11478624b1a69ff |
blazor-dal-login-redacted.mp4 |
93b06122ef6edc792b9b1c794dc512719da28e9fe087191f16a58681ffb2f152 |
no-logout-route-guard.json |
22bd3a660b2d803d417a9c5328c70feedda8fddfe7ff017775fc982e2ccc57ce |
teardown.log |
b967b8d652f7f638db40afb522c9762c55c8dec0d7c4ff7669d1c8170b23b030 |
The user clarified that acceptance must exercise the Blazor-hybrid implementation, not legacy XAML sign-in. The earlier no-logout device reproduction invoked the registered native LoginPage through MauiDevFlow because Blazor /login redirects authenticated members home. That was an inappropriate substitution for the intended UI flow.
The visibility recording below is valid evidence of a legacy native sign-in return exposing outgoing content, but it does not establish a failure of the Blazor sign-in transition. Its prior classification as a Blazor acceptance blocker is withdrawn. The suggested neutral native cover is not an approved or required correction for this Blazor-focused task. Historical measurements remain intact, clearly scoped to the path actually exercised.
Source inspection confirms that Main.OnLocationChanged redirects authenticated /login arrivals to /alpa. The supported Profile action calls LogOutAsync, then navigates to the Blazor home; its LOGIN action opens the Razor login form. No user-facing no-logout account switch was found in that Blazor flow. Therefore:
No application code was changed or reverted for this scope correction.
Tested revision: db19d810e094a9f8dc6d20a29f977afab8ea9048. Its application/test sources are identical to correction 6c729bb7f29a1143606eeb1faa3cc498302679fb; only documentation changed after that correction. The user explicitly requested verification of the previously unresolved transient visibility. No application code or test data was modified for this run.
Legacy native-path failure: native sign-in return briefly exposes the outgoing UAL home before the skeleton is rendered. This was incorrectly treated as a Blazor acceptance result; see the scope correction above. The measurement is retained as native-path evidence only. Blazor device acceptance remains incomplete.
Created dedicated iPhone 15 Pro / iOS 26.5 simulator AB2081-ServiceLayerIntegration01-Visibility04, UDID CC14AA0B-F775-48B8-89EE-74CEEECBF1D8. The normal signed iOS Debug build used --no-incremental, RuntimeIdentifier=iossimulator-arm64, MauiDevFlowPort=61792, -m:1, and -nr:false. Result: 0 errors, 676 warnings, 26.58 s. Before its single launch, strict signature verification passed and source/installed DLL and executable hashes and nanosecond mtimes matched:
| Artifact | SHA-256 | Source and installed mtime (ns) |
|---|---|---|
ALPADocs.dll |
4d1ea4c490ea47ae286a75999677969c7ab6a407a6afa2674762583429ba9c34 |
1790099492729417919 |
ALPADocs |
cc9acd0f7b2778c5449f4e18a22a7b59e2a56c54c0e6828730ba6eac2090bf46 |
1790099499395395994 |
UAL and DAL credentials came privately from the previously approved vault test roles. A read-only JavaScript probe recorded MutationObserver events, requestAnimationFrame samples, and Page Visibility events. A visible UAL home provided a positive control, then native LoginPage covered it. The native login was submitted through a real Appium/XCUITest touch. One setup locator failed before submission and was replaced with a verified native touch; no failed authentication was retried. The probe did not alter DOM, application state, or timing with intentional delays. Its measurement overhead is not claimed to be zero.
The native simulator recording contains 119 decoded frames over 4.741714 seconds. Credential-field bands were masked before media inspection; the unredacted raw recording was deleted. This mask leaves the native header, outgoing home heading and bottom navigation visible throughout. The recording's actual frame timestamps are retained; it is not a claimed 60 fps or exhaustive display-frame capture.
All clock times below are UTC from the browser trace on 2026-09-22.
| Time | Observation |
|---|---|
| 17:57:19.068 | Webview becomes visible. Its first frame callback still contains UAL feed/menu; no DAL and no skeleton. |
| 17:57:19.117 | Mutation callback contains UAL home plus DAL navigation, with visibility visible. |
| 17:57:19.119 | Outgoing feed has been cleared; DAL navigation and home skeleton are in the DOM. |
| 17:57:19.125 | First subsequent frame callback contains the skeleton and no UAL. |
| 17:57:20.882 | Frame callback contains DAL home, with no UAL and no skeleton. |
The original 2 ms mixed DOM overlap was reproduced. No animation-frame callback contained both UAL and DAL, but that did not prove isolation: one callback after return still contained UAL alone. Of 330 total frame callbacks, 79 were visible UAL positive controls before re-entering native login. Of the 251 after return, 1 contained UAL, 92 the skeleton, and 158 DAL. The page was hidden between native entry and return.
Video frame 25, presentation timestamp 1.606914 s, visibly exposes a strip of the outgoing UAL page at the left edge of the native pop animation. The old welcome/contract content and PDR / SUBMIT tab are visible. Frame 26, timestamp 1.633257 s, replaces that strip with the neutral skeleton and seed navigation; DAL content arrives later. The 26.343 ms between these recorded frames is sampling evidence, not a precise bound on the stale content's total display duration. Video and frame callbacks independently confirm a visible outgoing frame, rather than merely a hidden DOM mutation.
Source inspection supports a native-navigation/render ordering gap:
Authentication.Session.cs publishes Changed and returns successful authentication.AlpaIHomePage.OnSessionChanged schedules clearing with _ = InvokeAsync(...); the event publisher does not await that render reaching the webview.LoginPageViewModel awaits authentication, then immediately calls PopToRootAsync. The native pop can reveal the previously rendered webview before its neutral frame lands.Earlier native-path recommendation, now outside this task's clarified scope: coordinate native return with Presentation invalidation. Keep an opaque neutral native cover over the returning webview until the outgoing member's rendered frame has been replaced by a neutral skeleton (or verified incoming-member frame), then uncover it. Do not treat Changed, StateHasChanged, authentication completion, or a fixed sleep as proof that the outgoing pixels are gone. A render acknowledgement must account for hidden-webview frame callbacks being suspended. Reuse the existing navigation/presentation boundaries, review the design, and add a transition-level regression before another device run. No service-layer patch or navigation workaround was applied during this verification.
Legacy native-path visibility failed; Blazor account-switch visibility is unverified. Remaining controlled failure scenarios, FTDT correctness, cookie/favorites isolation, and Android acceptance were not advanced after this failure. Automated correction results remain Debug 2,920 / Release 2,914 / Docs 4, four matrix builds with zero errors, and 75 routes / 0 gaps; no source change justified rerunning that completed matrix.
Only this run's Appium session/server and dedicated simulator were torn down. Simulator removal and server exit were verified. Evidence is local under /private/tmp/AB2081-ServiceLayerIntegration01-visibility04/, with a selected-file manifest in evidence-sha256.json. The probe, complete trace, recording, frame timestamps, decoded frames, contact sheets, logs, installed-build proof, and teardown remain available locally.
| Evidence | SHA-256 |
|---|---|
ios-installed-build.json |
71d6213848934903980b930551be43289fdab0442f80464f25c5fa0adc86006e |
probe.js |
bd121849d212b9de5652c5a5ba13c3351cb627a19b419cc01318273b331096dd |
visibility-trace.json |
faded0c5c1ad7a94186403560791b034d05074e62e0696ddd16cadcc89601625 |
visibility-transition-redacted.mp4 |
1ed3547f11b4b3d73139c5ee5b169b5935374121bd0a4bad8fc3a69818853fd8 |
video-frame-timestamps.json |
70fd72515f31cc19faec4519287f06fc823ee86cfd530eb7bdc8c916661e5cd8 |
frames/frame-025.png |
5612bf295b606e713662a53bb39f1c3eb1c564af9d3eabbc33e6b566c6ef1cf2 |
frames/frame-026.png |
70485dff3340008ab1fb3734d862ad1f77703d42b9dd94d2988a31983183a168 |
teardown.log |
e155b3a48578c87ee294a6610bc2d94ced3012637b8920a95828fc3a020f7bf8 |
Current application revision: 6c729bb7f29a1143606eeb1faa3cc498302679fb on imp/blazor-hybrid-service-layer-decoupling. The user approved implementing the correction and validating it before resuming acceptance. The code commit passed all applicable hooks without bypasses. This record's subsequent documentation commit changes no application code.
The retained home listened only for a boolean login transition; A-to-B sign-in publishes ISessionState.Changed while keeping IsLoggedIn true. The Presentation correction observes the published member context, clears outgoing home/menu/contract state, and prevents late outgoing async work from replacing incoming content. Same-member token refresh preserves presentation. See the investigation and regression evidence.
The persistent UAL-home reproduction was corrected through the native sign-in test path. The later native visibility failure does not establish a Blazor UI failure. Full Blazor device acceptance and the final integration PR remain gated on uncompleted walkthroughs. Historical failures and their original evidence remain below; they are not results for this corrected revision.
The complete matrix ran before resuming acceptance. It tested staged tree 56952313552ca638d883a5da5b68ccee4b608005, based on 0cc67515d24994ef439252453caac37f51d876a0; its application and test sources match 6c729bb7. Only the investigation document differs. Fifteen added tests raise the earlier Debug/Release baselines from 2,905 / 2,899 to 2,920 / 2,914.
| Check | Result |
|---|---|
| Debug unit + architecture | 2,920 passed, 0 failed, 0 skipped |
| Release unit + architecture | 2,914 passed, 0 failed, 0 skipped |
| DocsTests | 4 passed, 0 failed, 0 skipped |
| ios-debug | 0 errors, 650 warnings; 7.56 seconds |
| android-debug | 0 errors, 676 warnings; 37.91 seconds |
| ios-release | 0 errors, 653 warnings; 16.38 seconds |
| android-release | 0 errors, 679 warnings; 79.88 seconds |
| Navigation freshness | Current |
| Gateway catalog | 75 routes, 0 gaps; catalog regression passed |
| TRX | SHA-256 |
|---|---|
correction-full-debug02.trx |
2246b49df381e0b541bf34acb7263ef31185a0651acf3b4c774649b2ce341484 |
member-correction-matrix-release.trx |
d5d69b3502b63f9f2bb831bf8a4b4f569928767d67535b0a354422d3260912fc |
member-correction-matrix-docs.trx |
f2a9fc8232b4aad69009827ec173a2a8cc9c7384cef6fb94ab66388106eea7b9 |
Commands follow the Reproduction commands section with unique TRX names. Full logs, TRXs, command metadata, and intermediate failures are preserved locally under /private/tmp/AB2081-home-member-regression/, with remaining matrix output in matrix/. The code commit's hooks independently passed the 50-test architecture subset and full 2,920-test suite. Compilation-only iOS matrix artifacts have signing disabled and were not installed for acceptance.
Created dedicated iPhone 15 Pro / iOS 26.5 simulator AB2081-ServiceLayerIntegration01-iOS03, UDID EB89EAAC-A013-4CFD-8AEF-A8BB32325FA4. Built revision 6c729bb7 with normal simulator signing:
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Debug --no-incremental \
-p:RuntimeIdentifier=iossimulator-arm64 -p:MauiDevFlowPort=57477 -m:1 -nr:false
Before its single app launch, source and installed DLL/executable SHA-256s and nanosecond mtimes matched, and strict signature verification succeeded. Installed ALPADocs.dll: SHA-256 4333e3b022e52a70388f447f87bac0cf9cf940b4e144bd1a6a025b4b882b4c5b, source/installed mtime 1790097272649101478 ns. Installed executable: SHA-256 65c744e4d0b7ddce917c0412a5204c869d75ba0d2430128f9434ec09c40e54da, source/installed mtime 1790097278991743735 ns. No crash occurred during this walkthrough.
The approved UAL and DAL UI-test roles were read privately from . UAL signed in and initialized its home, MEC content, and United Pilot Contract (UPA23.3). The existing native LoginPage allowed DAL sign-in without logout while retaining the Blazor home. Submission and subsequent UI interactions used real Appium/XCUITest touches. On return, the visible home showed DAL MEC, DAL resources, Delta imagery, Delta PAN, and DAL navigation. Profile confirmed DAL. The drawer and MEC page showed DAL content. Opening the same AppContractLink query tag rendered the Delta Pilot Working Agreement, visually confirmed after dismissing the optional offline-download prompt. Four PDF canvases were present. No Blazor error indicator was visible in the captured pages.
A DOM mutation trace recorded a 2 ms overlap of UAL home text and DAL navigation during the native sign-in transition, followed by DAL-only content. That trace does not prove whether the underlying webview was visible for those mutations. The final visible home is correct, but this run does not establish the stricter account-isolation requirement that B never sees A, even transiently. Favorites were empty, and cookie isolation was not exercised. No synthetic member data was seeded.
| Walkthrough | Result on corrected revision | Evidence / remaining limit |
|---|---|---|
| Signed iOS launch | Passed | Installed identity/signature verified; stable throughout walkthrough |
| Retained home after A → B, no logout | Passed for original reproduction | Returned visible home, drawer, MEC and contract all DAL; profile confirms DAL |
| Complete account isolation | Partial | 2 ms DOM overlap visibility unresolved; empty favorites and cookies do not prove isolation |
| Interrupted switch | Not run | Controlled mid-request setup not supplied |
| Rejected / locked credentials | Not run | Approved failure fixture/operator procedure pending |
| Slow / offline logout | Not run | Approved scoped network setup pending |
| Expired-session resume | Not run | Approved expiry/stalled-request setup pending |
| Home / theme / feed recovery | Partial | Correct DAL home/images observed; placeholder timing and failure recovery not fully exercised |
| Document viewer | Partial | UAL and DAL PDFs rendered; controlled 30-second catalogue delay not exercised |
| FTDT synchronization | Not accepted | Duty-period correctness and duplicate-error behavior not walked through |
| iOS cancellation / cross-host redirect | Not run | Approved controlled request/redirect setup pending |
| Android acceptance | Not run | Full cross-platform device acceptance remains open |
The user was asked to identify approved backend/network fixtures or operator procedures for the remaining controlled scenarios. Normal UAL/DAL credentials do not supply those conditions. No account lockout, shared network disruption, backend mutation, or fabricated passing result was used. No final integration PR was opened.
The run's Appium session was deleted, its own server was stopped, and its dedicated simulator was shut down and deleted with teardown-sim.sh; removal was verified. No other simulator, agent, or worktree was modified. Evidence remains local under /private/tmp/AB2081-ServiceLayerIntegration01-acceptance03/; it is not an uploaded CI artifact. The complete selected-file manifest is evidence-sha256.json.
| Evidence | SHA-256 |
|---|---|
ios-installed-build.json |
82c2251f2c626ec71b7d4dc5fce6694577fba3f7183df05ed16dd88d3e63f69d |
ios-ual-switch-baseline.png |
44851a2b53380da2407e384260ef6fd6f643b101d59fbb048765cbd503065e10 |
ios-dal-after-switch.json |
9b69f3241018c3ad90c75c1f973bc20de385559ae2f01dac489a5661ef5dd012 |
ios-dal-after-switch.png |
1351f7a983bacd6a536357ee48ad71e88d710c30638978ba5c0b30a02f2839c5 |
ios-dal-contract-rendered.png |
772fcc27d0b1f372e2950c3cf95618d913144080eb7a4d639b658e0b9edaf0c6 |
ios-switch-transitions.json |
0a80b8b9da4adaaee0f7d997652cd833afabdd92730d1f8a370922f3ae399c3f |
teardown.log |
41d5ac5a879d5afc2b97e98e41a938f6d45c2266ccf0c35950c755d8bb3857ac |
Tested code revision: f8f875d0bba1a5c3993c7a8b8fdbbdd126136808 on imp/blazor-hybrid-service-layer-decoupling, with SDK/workload set 10.0.400. The documentation commit carrying this record changes no application code. Automated validation passed. Corrected simulator signing now permits launch, but device acceptance failed the UAL-to-DAL account-switch check recorded below. The final PR remains blocked.
All nine PRs completed in the required order using noFastForward merge commits, without squash, rebase, votes, policy bypasses, or source-branch deletion. After each completion the integration worktree pulled the merge and ran the full Debug suite. Every resulting tree matched that PR’s source tree exactly.
| PR | Merge revision | Debug passed | Failed | Skipped |
|---|---|---|---|---|
| 2505 | 92cfaec8d2e4698ff5a092862de9f7820286c08d |
2080 | 0 | 0 |
| 2509 | 04ac24630a6a6fa3c6a8b0eaa76f55dbcaf2c02b |
2177 | 0 | 0 |
| 2510 | ced89ec7fa54de279ed4e98c024ce8627b691a91 |
2234 | 0 | 0 |
| 2511 | c6291ffa245d81da1790558bb0c8d3699d2486c0 |
2375 | 0 | 0 |
| 2512 | f4380bf95b0abfc29c69a9535f831ff56bffd9ad |
2422 | 0 | 0 |
| 2513 | e4660346dcdaa5c81aa85f20cb30834f2beb60f8 |
2473 | 0 | 0 |
| 2514 | a23761a3c2cc2e7a8fef7e04fab507028ac43c7a |
2587 | 0 | 0 |
| 2515 | 77f1a15d6ede2d91fafc5f4150855fbee4b6f8dd |
2607 | 0 | 0 |
| 2527 | 42187343601aad7cc19bb7827b97b7ef57e53673 |
2905 | 0 | 0 |
PR 2515’s corrected baseline is 2,607, as its description and implementation record state at 6633bb59c692e81fad19fd48286bc7cf48c1fe55. The hand-off had incorrectly attributed the later review revision d2e6a211f56ce7a1808807e1f46074054c494759’s 2,887 tests to PR 2515. The user approved this correction before completion resumed. PR 2534 is already contained in PR 2527’s source ce46a36a781231503e45ebef0b43b21f49fb18cf; no extra merge was performed for it.
043bd15daae18a6781ef6e4be1af978d7a9d324c merged as 5f41275e8e7061c8ff7fca9d58606a1825bcde49. The merge was clean and its tree exactly matched the reconciliation source. The runbook’s existing textual and namespace resolutions were retained; no new resolution was needed.725304b3 to 883339121ad38552980e559b10c257d0bf208c42, carrying PR 2528’s hero-card CSS change. It merged cleanly as the tested revision above; no manual resolution was needed.alpa-components.css matches the app branch byte-for-byte: Git blob d160ef50e4b6180712a5c119379d263ce672634c.| Suite | Passed | Failed | Skipped | TRX |
|---|---|---|---|---|
| debug | 2905 | 0 | 0 | integration01-matrix-debug.trx |
| release | 2899 | 0 | 0 | integration01-matrix-release.trx |
| docs | 4 | 0 | 0 | integration01-matrix-docs.trx |
| Build | Result | Errors | Warnings | Elapsed |
|---|---|---|---|---|
| ios-debug | Passed | 0 | 650 | 14.9 s |
| android-debug | Passed | 0 | 676 | 48.5 s |
| ios-release | Passed | 0 | 653 | 20.06 s |
| android-release | Passed | 0 | 679 | 90.07 s |
Navigation regions are current. Gateway catalog: 75 routes, 0 gaps; the catalog regression test passed. Full logs are retained locally under /private/tmp/AB2081-ServiceLayerIntegration01-evidence/; the first phase’s log is /private/tmp/AB2081-ServiceLayerIntegration01-pr2505-debug.log. TRXs remain in the worktree’s ignored UnitTest/TestResults/ and DocsTests/TestResults/ directories. These are local evidence files, not uploaded CI artifacts.
iOS targets iossimulator-arm64 with signing disabled; Release also disables archiving. These builds do not establish signed-device/AOT behavior or complete trimming safety.
Commands ran sequentially at the tested revision with one MSBuild worker and node reuse disabled, preserving complete output.
dotnet test UnitTest/UnitTest.csproj -c Debug -m:1 -nr:false --logger 'trx;LogFileName=integration01-matrix-debug.trx'
dotnet test UnitTest/UnitTest.csproj -c Release -m:1 -nr:false --logger 'trx;LogFileName=integration01-matrix-release.trx'
dotnet test DocsTests/DocsTests.csproj -c Debug -m:1 -nr:false --logger 'trx;LogFileName=integration01-matrix-docs.trx'
dotnet run docs/build-nav.cs -- --check
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Debug -m:1 -nr:false -p:RuntimeIdentifier=iossimulator-arm64 -p:EnableCodeSigning=false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-android -c Debug -m:1 -nr:false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Release -m:1 -nr:false -p:RuntimeIdentifier=iossimulator-arm64 -p:EnableCodeSigning=false -p:ArchiveOnBuild=false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-android -c Release -m:1 -nr:false
python3 scripts/gateway-readiness-check.py --catalog-check
python3 scripts/gateway-readiness/test_catalog_check.py
| TRX | SHA-256 |
|---|---|
integration01-pr2505-debug.trx |
62bef3ffc10d7dda126b344655fb35158f41cda8e4794903be7591b39530ed7e |
integration01-pr2509-debug.trx |
d11c06e9de5b5a70c11133923436d7ddc4c342924d7e3152286168f08e2a4118 |
integration01-pr2510-debug.trx |
0d71255f553a61e892b14992891fb3169e0a1bb235c062634e001e34a8aa4638 |
integration01-pr2511-debug.trx |
473027c8cc8fb19355c88deb88a88548e12cec9ccca5e33300bcb921d4b8f414 |
integration01-pr2512-debug.trx |
9f80c1568aaa6221226f4ee73395514b53315dc1321e483d4f9a280f50a882bb |
integration01-pr2513-debug.trx |
a5a49fcbc56ce071b019c0add29515b93d55b9c9705c30eda01c1dfbe2308644 |
integration01-pr2514-debug.trx |
85ba841a97a0493c24aa9cbde0992565372cfb496b47ed81c557eaa979d7ed55 |
integration01-pr2515-debug.trx |
afba1ce4b03c0ecdaec8837b6f754e1c53c264a0299a569cd6c0529f6e9a4df8 |
integration01-pr2527-debug.trx |
ce40ab4d6f70ddc7f185593be88231e4a5752d609719083290060075df1960c5 |
integration01-matrix-debug.trx |
6c8b03097b53cacd42c8211b2ee69daf69dc8da8e75442485ce5e2ce3cbb9e75 |
integration01-matrix-release.trx |
1337a68df5b58929b582e96b805045f430f585955340334aed5bb0b80a9a9190 |
integration01-matrix-docs.trx |
21a0337f02787e7271c50c52c0199ce21da2f6a2c577748d6325c177ebfdd651 |
Candidate: 557610c9c207a5a22a0c4eaad2850cc628a23186 (documentation-only child of validated code revision f8f875d0bba1a5c3993c7a8b8fdbbdd126136808). The dedicated simulator was AB2081-ServiceLayerIntegration01-iOS, iPhone 15 Pro / iOS 26.5, UDID 351E79AF-6803-4B38-8DC8-5492D99BF557.
A fresh --no-incremental Debug simulator build succeeded with zero errors. Before launch, the installed ALPADocs.dll and native executable matched their source SHA-256s and nanosecond modification times. DLL SHA-256: 49b47a57700d9693b755cbcaaf4f6f434e78521645a7cb5b5466964898cfea6c.
Launch failed. At 12:12:04 ET on 2026-09-22, process 2428 was terminated with SIGKILL (Code Signature Invalid), termination namespace CODESIGNING, code 2, Invalid Page. The matching crash report names this simulator and installed bundle. The stack is in the native loader; no MauiDevFlow agent registered. The simulator remained booted and the screenshot shows SpringBoard. Read-only codesign --verify --deep --strict returned exit 1: code has no resources but signature indicates they must be present.
The launch build incorrectly retained -p:EnableCodeSigning=false from the compilation-only matrix. Simulator deployment signing must be corrected before a further acceptance attempt. No service-layer code was patched, no relaunch was attempted, and no test-account sign-in occurred. The UAL/DAL production UI-test account roles were identified in Key Vault, but credential values were not retrieved. Only the owned simulator was torn down after evidence capture. Android acceptance was not started because the runbook requires stopping on failure.
| Walkthrough | Result | Evidence / reason |
|---|---|---|
| Initial iOS launch | Failed | Invalid code signature; crash report and signature check below |
| Account switch A → B | Not run | App terminated before initial sign-in |
| Interrupted switch | Not run | Stopped at launch failure |
| Rejected / locked credentials | Not run | Stopped at launch failure |
| Slow / offline logout | Not run | Stopped at launch failure |
| Expired-session resume | Not run | Stopped at launch failure |
| Home / theme / feed recovery | Not run | Stopped at launch failure |
| Document viewer | Not run | Stopped at launch failure |
| FTDT synchronization | Not run | Stopped at launch failure |
| iOS cancellation / cross-host redirect | Not run | Stopped at launch failure |
Evidence is retained locally under /private/tmp/AB2081-ServiceLayerIntegration01-evidence/:
| Evidence | SHA-256 |
|---|---|
ALPADocs-2026-09-22-121205.ips |
b5c75472ec107f15fc80ae9fabcffa7eddf56608ce41e2ea3e241e8399269606 |
device-ios-after-crash.png |
9b675b09a1b53a3a15a709539f0e416f91f67361fd616486604df6292b085f0b |
device-ios-codesign-verification.log |
0e28b2113f7c896d993ce4e1e3eb9b107f3d2c5521fefc4af944ffdb5e33df72 |
device-ios-installed-build.json |
6994f1b4de2d54a968ed7bf6b405f607f8f43c2e41d408fcfb44210d59b6b648 |
device-ios-build.log |
c4749f930b60de47fd4d032a30f749ffcf8b0198ebac5d10e6c5336c0b9ad2e7 |
Step 4 has not passed. The final integration PR was not opened, and auto-complete was not enabled.
Validated on 2026-09-22 with the repository-pinned .NET SDK/workload set 10.0.400.
Tested code revision: be3c7a102e4b7aedf15f97e6e9ce44b8ff77a84e on fix/AB2081-service-layer-review-fix-01. This includes Phase 7 6633bb59, the PR 2522 corrections, app branch snapshots 4774e079 and 5152a5c4, and the second-pass remedies R01–R11 recorded in the finding ledger (b1644573 through b31eb6b8) and the transport tuning in be3c7a10 (2 s retry base; JWT exchange capped at one retry). Every suite and build below ran at this commit from a clean worktree. The follow-up evidence commit changes documentation only. The previous record, for d2e6a211f56ce7a1808807e1f46074054c494759, is superseded by this one. PR 2534 (af15a0bc, merged into this branch as ce46a36a on 2026-09-22) is not part of this exact-revision run; its evidence is the pre-commit hook suite (Debug 2,905 passed) and the reconciliation branch's own matrix in the integration hand-off.
These are cumulative-tip results. Earlier phase counts in the implementation history remain historical and do not certify those earlier revisions for independent release. See the finding ledger for all 118 dispositions and the test migration map for removed fixture replacements.
| Suite | Passed | Failed | Skipped | Local TRX filename |
|---|---|---|---|---|
| Debug unit + architecture | 2904 | 0 | 0 | fix01b-debug.trx |
| Release unit + architecture | 2898 | 0 | 0 | fix01b-release.trx |
| Documentation | 4 | 0 | 0 | fix01b-docs.trx |
The 50-test architecture subset is included in both full suites and also ran, via the pre-commit hook, on each of the eleven remedy commits; no separate TRX is retained for it. The six-test Debug/Release difference is MockThemeApiClientTests under #if DEBUG (the mock theme client ships only in Debug); neither run skipped tests. Relative to the superseded record, Debug gained 17 tests and Release 17: the R01–R11 regression cases. The documentation result comes from DocsTests/DocsTests.csproj, independently of the legacy pre-commit Docs filter on UnitTest.
Intermediate failures were inspected in uniquely named TRX files before correction: missing-cache-directory deletion, persisted-document fixtures, an FTDT self-heal fixture, cancellation fixtures, and a composition fixture that reached portable native version tracking. The final suites above include the corrections and all new regression cases. No failing suite was bypassed or rerun without diagnosis.
The second pass had its own intermediate failures, each diagnosed before the commit that carries the fix: the first cut of the R05 identity marker discarded rows that had no marker and added a store read to ordinary keys (10 failures; the marker is now identity-bearing-only and a missing marker is compatible); R08's cookie clear tripped the throwing platform leaf in two real-graph tests (a recording port replaces it); R10's first cap raced the deadline timer (2 failures; the wait is now infinite on the token); R11's ValidateOnBuild surfaced five head adapters that depend on AddPresentation() or the Blazor host, which the graph does not compose and which are excluded by name. One commit (R07) used SKIP_SECRET_SCAN=1 because the scan flags pre-existing non-secret lines in whole staged files; the reason is in its message.
| Build | Result | Errors | Warnings | Elapsed |
|---|---|---|---|---|
| ios-debug | Passed | 0 | 650 | 6.6 s |
| android-debug | Passed | 0 | 676 | 39.6 s |
| ios-release | Passed | 0 | 653 | 15.1 s |
| android-release | Passed | 0 | 679 | 78.8 s |
Build success is compilation/package evidence, not an on-device execution result. Both iOS builds target iossimulator-arm64 with code signing disabled; Release also disables archive creation. Android Release retains the repository's existing PublishTrimmed=false setting. These checks do not establish signed device/AOT behavior or complete trimming safety.
Additional checks:
alpa-components.css and ftdt.css blobs match app snapshot 5152a5c4 exactly.Resumed with user authorization on candidate 31b25f09de0a3babfb55800815a80b18758a38c7, whose application code is identical to validated revision f8f875d0bba1a5c3993c7a8b8fdbbdd126136808. The earlier signing failure above is historical; it was corrected by using normal simulator signing for deployment:
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Debug --no-incremental \
-p:RuntimeIdentifier=iossimulator-arm64 -p:MauiDevFlowPort=50419 -m:1 -nr:false
Result: 0 errors, 676 warnings, 16.72 seconds. The dedicated iPhone 15 Pro / iOS 26.5 simulator was AB2081-ServiceLayerIntegration01-iOS02, UDID 00912D34-2F44-429E-86BC-286263B57DD8. Before its single app launch, source and installed DLL/executable hashes and nanosecond mtimes matched; strict signature verification passed. Installed ALPADocs.dll SHA-256: 862ee8a7400f3e775c7de7d42295fc46757557c200175d80834ef73cacec71a3; source and installed mtime: 1790093815075674386 ns. No service-layer code was changed.
The user approved the UAL and DAL production UI-test roles from . Credential values were consumed privately and are excluded from this record. UAL signed in, loaded its home and MEC content, and downloaded/opened United Pilot Contract (UPA23.3). The screenshot shows the PDF rendered, not merely an opening indicator. The first-run optional automatic-download prompt was dismissed with Not Now.
Account switch failed at 12:32 ET on 2026-09-22. Reproduction and evidence:
/login route redirects an authenticated member home. Open the existing, registered native LoginPage route using MauiDevFlow, select ALPA Members, fill the approved DAL test credentials, and submit through a real Appium/XCUITest touch. This native form invokes BeginSignInAttempt and CompleteJwtSignInAsync.LoginSuccessful at 16:32:07.106543Z, and native navigation returns to the existing Blazor home. The resulting visible screen still shows UAL MEC, Access UAL documents, resources, and information, and UAL home content. The DOM capture agrees with the screenshot; the Blazor error indicator is not visible.The observed failure is stale UAL presentation after successful DAL sign-in. It does not establish that DAL read UAL's persistent document store or cookies. Favorites were empty for UAL, so their isolation was not proven. Read-only source inspection identifies AlpaIHomePage.OnLoggedInChanged returning when _feedInitialized is true as a likely investigation point; root cause has not been established. The recommended owner follow-up is to trace member/session change propagation into retained home/feed/menu state, clear prior-member presentation before rendering the new member, and add a regression covering an already-mounted home during A-to-B sign-in. Do not classify this as the excluded AB#2859 late-theme race without evidence; this run observed retained UAL content.
| Walkthrough | Result | Evidence / limit |
|---|---|---|
| Signed iOS launch | Passed | Installed identity and strict signature verified; app rendered and signed in |
| Account switch A → B, no logout | Failed | DAL session confirmed; UAL home remained visible after sign-in |
| Interrupted switch | Not run | Stopped after account-switch failure |
| Rejected / locked credentials | Not run | Stopped after account-switch failure |
| Slow / offline logout | Not run | Stopped after account-switch failure |
| Expired-session resume | Not run | Stopped after account-switch failure |
| Home / theme / feed recovery | Failed / incomplete | Stale UAL home observed; remaining recovery variants not run |
| Document viewer | Partial | UAL contract downloaded and rendered; controlled 30-second catalogue delay not exercised |
| FTDT synchronization | Not accepted | Completion message observed in sign-in logs; duty-period correctness not walked through |
| iOS cancellation / cross-host redirect | Not run | Stopped after account-switch failure |
| Android acceptance | Not run | Stopped after iOS failure |
Acceptance stopped after diagnosis and evidence capture. Only this run's Appium session, server, and dedicated simulator were torn down. No service-layer patch was made and no final integration PR was opened. Automated counts remain Debug 2,905 / Release 2,899 / Docs 4, all four builds with zero errors, and 75 gateway routes / 0 gaps; no application code changed after that matrix.
Evidence is retained locally under /private/tmp/AB2081-ServiceLayerIntegration01-acceptance02/:
| Evidence | SHA-256 |
|---|---|
ios-installed-build.json |
ee35534b564830107b62b49c0c309e563c9ffcabf2d589588f00702c4f2d2678 |
ios-installed-signature.log |
3c4068a2d7e4d7a8680e40df124b42044a2efda0c6fd9e32da7b8a344d0e629c |
ios-ual-contract-open.png |
8a700852625c4ea067d76e2133f4b2da6c1c8cce5710f9023801185163dec9eb |
ios-dal-after-switch.json |
988a567aee1a87f233d1f16dda7c17620360d2763efb8881b0a417be9466c3d8 |
ios-dal-after-switch.png |
a5ed0943bbb87fbfb04f1640e6aecdb847945b3d7c076dd99e577bc26316d6bc |
ios-switch-profile.json |
d35c21c1ab4087b3edaf6eedc9eb973e8bcc8df37c17d4bb467e0d3d62c76ca9 |
ios-switch-profile.png |
f0a45e5c1414937803280e40a87b0ad5a65b8ff4a7396860a763388ac0858ed4 |
ios-switch-logs.json |
be1a5be9ff56b98fe9b026e4635091874a42f1590587f80b616c931823028c2a |
ios-switch-transitions.json |
3a8e47bda7a31e094380b7534e0a8135f70ead9711f3f4942c918942611c8528 |
teardown.log |
e86203ce6d111d085af13e6ca4acf96d6935ff17eab873426bd0e2f9d4fffa89 |
All commands ran in sequence from one script against the checked-out revision. They use a single MSBuild worker and disable node reuse to avoid local shared-build contention. Full logs were retained, not reduced to summary output.
dotnet test UnitTest/UnitTest.csproj -c Debug -m:1 -nr:false --logger "trx;LogFileName=fix01b-debug.trx"
dotnet test UnitTest/UnitTest.csproj -c Release -m:1 -nr:false --logger "trx;LogFileName=fix01b-release.trx"
dotnet test DocsTests/DocsTests.csproj -c Debug -m:1 -nr:false --logger "trx;LogFileName=fix01b-docs.trx"
dotnet run docs/build-nav.cs -- --check
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Debug -p:RuntimeIdentifier=iossimulator-arm64 -p:EnableCodeSigning=false -m:1 -nr:false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-android -c Debug -m:1 -nr:false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-ios -c Release -p:RuntimeIdentifier=iossimulator-arm64 -p:EnableCodeSigning=false -p:ArchiveOnBuild=false -m:1 -nr:false
dotnet build ALPAMobile/ALPAMobile.csproj -f net10.0-android -c Release -m:1 -nr:false
python3 scripts/gateway-readiness-check.py --catalog-check
python3 scripts/gateway-readiness/test_catalog_check.py
Raw logs are local files under the reviewing session's scratch directory; TRXs are local ignored UnitTest/TestResults/ and DocsTests/TestResults/ artifacts. They are not claimed as uploaded CI artifacts. The compact summaries above and hashes below are checked in so the executed artifacts are distinguishable from historical runs.
| TRX | SHA-256 |
|---|---|
fix01b-debug.trx |
77dfa0e50ac55f86067c086b15cdfe49581c91011549fb8029f561f16268a502 |
fix01b-release.trx |
ddc8087edcdec66ac06782b3c11d4216fa5c7c01d9fa7972fd1be316bd3764e3 |
fix01b-docs.trx |
b6f1886c3eec7ad4ad1d21b430eea0d4a3210d822520fb46b4914cf944f2e76d |
This subsection describes the original review hand-off. Current correction and device results are recorded at the top of this file. At hand-off, no device walkthrough or Appium run was claimed. P7-A4/P7-A5 remain open. Exercise both platforms for account switch, rejected/interrupted sign-in, slow/offline logout, resume with an expired session, home/theme/feed recovery, document download/viewer and FTDT synchronization. Verify native iOS cancellation timing and cross-host redirect bearer handling on device. F68 retains guarded synchronous effect startup; no device contention measurement is claimed.
Implementation and this correction PR target imp/blazor-hybrid-service-layer-decoupling. Complete the phase PRs in order, then this correction, with explicit human review. Do not merge the integration branch into imp/blazor-hybrid until the device gates pass. Automatic completion remains disabled for this correction PR.