On round-two device QA, I tapped Back from Day mode in the Accounts calendar. It should have returned to the full-screen calendar. Instead it returned to Accounts — skipping the calendar level entirely, dropping me back at the start of the navigation stack as if Day view had been the first screen I’d opened.
The Xcode simulator had never flagged this. SwiftUI previews had passed every check across the Accounts build arc.
This was A8 in the round-two findings document.
What the build was
Sprint 2 started with a straightforward brief: replace the placeholder dashboard with a real Accounts module. AccountListView — a SwiftUI List with a total-balance hero at the top, account rows showing name, type badge, and balance, swipe-to-delete, and a “+” toolbar button. Functional. Correct in preview. Uncomplicated.
Phase K rebuilt it. The brief deepened: total-across-accounts hero with a rotating sigil, a 30-day balance trend chart, and a horizontally-scrollable daily-activity strip for mint-in and spend-out transactions. Three stacked modules. Preview looked good. Xcode build: clean.
Phase O deepened it again, and the scope shift happened mid-design. The original ask: click the calendar strip to see more. The actual ask, once the design conversation was underway: click the calendar → full-screen month view, click a day → day detail mode. Three navigation levels. AccountsView → CalendarView → DayView. Settled through conversation, not a spec written upfront.
The NavigationStack was managing all three. Previews said it was fine.
The first device install
After phases J, K, L, and M were complete, I code-signed the build against my Apple Development identity and installed it on AnF — my physical device, the one in daily use. That was the first time any of this had run on real hardware.
Not a simulator. Not a preview. The actual device, in hand, with a real display and real touch input.
It found things. Not catastrophic failures. The kind of gaps that don’t register in preview because preview isn’t navigating — it’s rendering a static snapshot of a single view state. On AnF, you are actually tapping. The navigation stack actually moves. The gesture recognisers are real.
The QA pass drove a branch of fixes. Then round two.
What round two found
Round-two QA has a document: docs/qa/2026-06-18-round-2-findings.md. The A8 entry is the calendar back-nav.
The path: Accounts → tap calendar → CalendarView (full-screen) → tap a day → DayView. Back from DayView should pop one level: return to CalendarView. That is how a NavigationStack is supposed to behave — Back pops one item from the path.
Instead: Back from DayView popped all the way to AccountsView. CalendarView was gone.
The fix is A8 in the round-two branch. It went in alongside brand font confirmation and a twenty-palette library. All verified on device before merge.
What previews actually check
SwiftUI previews are rendering checks. They confirm that a view, given a piece of state, renders correctly. They catch layout failures, missing data, colour issues across light and dark mode. They are fast and they are useful.
They do not navigate. They do not run a NavigationStack. They do not exercise the Back gesture or the Back button under real conditions. They don’t know whether pressing Back from DayView pops to CalendarView or to AccountsView — because the preview never ran the sequence. It only ever showed one view in isolation, with mock state, looking correct.
The gap is structural. Xcode previews are designed for fast, isolated rendering feedback. They are not designed to orchestrate a multi-view navigation sequence. That distinction is obvious once you state it. Before AnF, it wasn’t being applied.
That is not a deficiency in SwiftUI previews. That is what they are. The deficiency is assuming they cover navigation correctness when they are only checking view-level rendering.
Three-level navigation is the point at which this assumption becomes costly. One level: Back goes to root. You can reason about that without running the sequence. Two levels: Back goes to the intermediate. Still auditable in isolation. Three levels with a full-screen presentation at level two: the NavigationStack is doing real work, and the only way to verify it is to run the sequence on a device and press Back.
The simulator is closer to preview than it is to the device. It runs the code; the stack executes. But gesture recognisers, rendering pipelines, and navigation edge cases differ between the simulator and physical hardware. The back-nav bug may have reproduced on the simulator if specifically tested — but it was never specifically tested there, because preview had said everything was fine.
The gap in the process
Phases J through M completed before a device was involved. That covers the Accounts CRUD foundation, the Phase K module redesign, and everything before Phase O. Phase O added the three-level NavigationStack.
That deepening was the trigger. Not a nice-to-have device check, not a QA pass for completeness. A navigation depth increase of this kind requires a real install and a real walkthrough before the next phase starts. It didn’t happen until the full arc was complete.
The cost: one regression, one round-two finding, one fix branch, one re-verification on AnF before merge. Not catastrophic. But findable at Phase O, at lower cost, if the install had happened then rather than at arc end.
Code-signing and device deployment takes time. Not something to do after every commit. But after every navigation depth change — that is the trigger. Not phase count. Navigation depth.
The gate
Round two is the second iteration of a gate that now runs on every significant navigation change. The findings document is docs/qa/2026-06-18-round-2-findings.md. A8 is the calendar back-nav. A8 is closed.
A8 implies A1 through A7. The document is the ground truth for what was found. Round two is not the last pass. When the next phase adds a navigation level, AnF goes back in the loop at the close of that phase, not at the end of the arc.
Previews and simulator stay in the workflow. Fast feedback on layout, state, and rendering — nothing replaces them at that layer. For navigation correctness on a three-level stack, they are supplementary. AnF is the check that counts.



