Repository navigation
Measure production mail-shell release budgets - #269
Conversation
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughSummary
Affected areas
Privacy and security
Migrations and configuration
Validation
WalkthroughThe mail shell now exposes launch and rendered-thread tracking hooks. ChangesMail-shell release measurement
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ReleaseTest
participant RootView
participant AccountView
participant MailShellThreadList
participant MailShellReleaseBudgetDriver
ReleaseTest->>RootView: launch signed-in mail shell
RootView->>AccountView: build content from account snapshot
AccountView->>MailShellReleaseBudgetDriver: attach mailbox selection handler
AccountView->>MailShellThreadList: provide item render callback
MailShellThreadList->>MailShellReleaseBudgetDriver: record rendered thread item
ReleaseTest->>MailShellReleaseBudgetDriver: wait for expected mailbox items
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubCodex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback". |
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift (1)
4463-4618: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winExplicitly tear down each hosted launch view
releaseFixtureWindowonly makes the window visible, and loop cleanup only setsisHidden. This does not guarantee thatAccountView’s.onDisappearruns. Add explicit teardown soMailboxWorkCoordinator.shareddoes not retain each iteration’s registration andinboxViewModelclosure.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift` around lines 4463 - 4618, Explicitly tear down each hosted SwiftUI view before iteration cleanup so AccountView’s onDisappear executes. Update the launch, body, and draft hosting flow around launchHost, bodyHost, and draftHost to remove or dismantle their hosting controllers/views and release their windows, rather than only setting isHidden, ensuring MailboxWorkCoordinator.shared drops the iteration’s registration and inboxViewModel closure.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift`:
- Around line 4463-4618: Explicitly tear down each hosted SwiftUI view before
iteration cleanup so AccountView’s onDisappear executes. Update the launch,
body, and draft hosting flow around launchHost, bodyHost, and draftHost to
remove or dismantle their hosting controllers/views and release their windows,
rather than only setting isHidden, ensuring MailboxWorkCoordinator.shared drops
the iteration’s registration and inboxViewModel closure.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 795f0145-2f4f-4732-ba96-3c8ae773cd98
📒 Files selected for processing (3)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swiftapps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Apple · Unwired Mail
🧰 Additional context used
📓 Path-based instructions (3)
apps/unwired-mail/**/*.{swift,mm,m,h}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands; use
zsh scripts/check-apple-lint.zshfor formatting and linting and the specifiedxcodebuild testcommand for tests.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
SwiftLint runs in strict mode so warnings fail validation; use mise-managed SwiftLint and Xcode's
xcrun swift-formatwhere applicable.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
⚙️ CodeRabbit configuration file
apps/unwired-mail/**/*.swift: Prioritize functional correctness, data protection, and Apple platform
behavior over style already enforced by swift-format and SwiftLint.
Check actor isolation, cancellation, lifecycle transitions, persistence,
retry and offline behavior, and Keychain accessibility. Flag credentials,
tokens, mail content, or decrypted Product Sync data that can be logged,
persisted outside approved device-local storage, or cross a documented
privacy boundary. Require focused tests for changed behavior and failure
paths.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
**/*Tests/**/*.swift
⚙️ CodeRabbit configuration file
**/*Tests/**/*.swift: Verify externally observable behavior, privacy invariants, error paths,
cancellation or restart behavior where relevant, and deterministic
isolation. Flag fragile sleeps, ordering dependencies, and tests that
duplicate the implementation instead of exercising it.
Files:
apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
🔇 Additional comments (4)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift (1)
1007-1021: LGTM!Also applies to: 1027-1029, 1065-1077, 1095-1095, 1188-1195, 1400-1401, 1558-1558, 3119-3119, 3172-3172
apps/unwired-mail/unwired-mail/Features/Account/RootView.swift (1)
3-13: LGTM!Also applies to: 24-24, 33-40
apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift (2)
4303-4423: LGTM!Also applies to: 4435-4541
7431-7560: LGTM!Also applies to: 8143-8143, 8177-8221
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift (3)
1032-1035: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick winUse constant-time membership tracking for rendered rows.
recordRenderedItemscans the fullrenderedItemsarray for every row appearance. This makes tracking O(n²) on the main actor. The release helper reads onlyid, but the driver stores each completeMailShellThreadListItem. Track identifiers in aSetand retain only the data required by the measurement.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift` around lines 1032 - 1035, Update recordRenderedItem to use a Set of item identifiers for constant-time duplicate checks instead of scanning renderedItems. Retain only the measurement-required item data while preserving the existing release helper’s identifier-based behavior, and update related storage and accessors consistently.
1417-1417: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winGate launch measurement on shell readiness and row rendering.
initialLaunchDidFinish()runs afterrefreshPinnedBodyPrefetch(...), but that method starts an unstructuredTaskand returns immediately. The release test also checks only for an expected thread ID initemDidRender. Add an explicitNavigationSplitViewshell-readiness signal, and wait for both that signal and a rendered row before recording launch time. Add focused success and timeout-path tests for shell readiness and prefetch ordering.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift` at line 1417, Update the launch measurement flow around itemDidRender and initialLaunchDidFinish() to require both an explicit NavigationSplitView shell-readiness signal and a rendered expected row before recording launch time. Ensure refreshPinnedBodyPrefetch(...)’s asynchronous work cannot allow measurement to finish prematurely, and add focused tests covering successful shell/prefetch ordering and the timeout path.Source: Path instructions
1574-1574: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick winGuard the launch completion callback against cancellation.
The canceled
.taskcan still reachinitialLaunchDidFinish()because synchronization converts cancellation into a normal return. Addguard !Task.isCancelled else { return }before the callback. Add a cancellation/reappearance test and run the specifiedxcodebuild testcommand after cleanup.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift` at line 1574, In the launch task flow immediately before initialLaunchDidFinish(), check Task.isCancelled and return when cancellation is detected so a canceled task cannot invoke the completion callback. Add a test covering cancellation followed by reappearance, then clean up and run the specified xcodebuild test command.Sources: Coding guidelines, Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift`:
- Around line 1009-1019: Update installSelectionHandler and the related
itemDidRender/releaseWaitForRenderedThreads flow to reset renderedItems whenever
a new shell owner is installed and associate render callbacks with the current
owner or generation. Ignore stale or late callbacks from prior owners so they
cannot release the wait before the current shell has rendered, and add a test
covering driver reuse across shell disappearance and reappearance.
---
Outside diff comments:
In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift`:
- Around line 1032-1035: Update recordRenderedItem to use a Set of item
identifiers for constant-time duplicate checks instead of scanning
renderedItems. Retain only the measurement-required item data while preserving
the existing release helper’s identifier-based behavior, and update related
storage and accessors consistently.
- Line 1417: Update the launch measurement flow around itemDidRender and
initialLaunchDidFinish() to require both an explicit NavigationSplitView
shell-readiness signal and a rendered expected row before recording launch time.
Ensure refreshPinnedBodyPrefetch(...)’s asynchronous work cannot allow
measurement to finish prematurely, and add focused tests covering successful
shell/prefetch ordering and the timeout path.
- Line 1574: In the launch task flow immediately before
initialLaunchDidFinish(), check Task.isCancelled and return when cancellation is
detected so a canceled task cannot invoke the completion callback. Add a test
covering cancellation followed by reappearance, then clean up and run the
specified xcodebuild test command.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0e1f2cad-8ba8-4dcb-96b9-1f23c8e5773b
📒 Files selected for processing (1)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Apple · Unwired Mail
🧰 Additional context used
📓 Path-based instructions (2)
apps/unwired-mail/**/*.{swift,mm,m,h}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands; use
zsh scripts/check-apple-lint.zshfor formatting and linting and the specifiedxcodebuild testcommand for tests.
Files:
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
SwiftLint runs in strict mode so warnings fail validation; use mise-managed SwiftLint and Xcode's
xcrun swift-formatwhere applicable.
Files:
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
⚙️ CodeRabbit configuration file
apps/unwired-mail/**/*.swift: Prioritize functional correctness, data protection, and Apple platform
behavior over style already enforced by swift-format and SwiftLint.
Check actor isolation, cancellation, lifecycle transitions, persistence,
retry and offline behavior, and Keychain accessibility. Flag credentials,
tokens, mail content, or decrypted Product Sync data that can be logged,
persisted outside approved device-local storage, or cross a documented
privacy boundary. Require focused tests for changed behavior and failure
paths.
Files:
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift
🔇 Additional comments (2)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift (2)
1059-1059: LGTM!Also applies to: 1081-1111
3135-3135: 🎯 Functional CorrectnessNo initializer update is required.
itemDidRenderhas a default no-op closure, and the only instance initializer passes the callback.> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb0a4ce874
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| viewModel: inboxViewModel | ||
| ) | ||
| let launchHost = UIHostingController( | ||
| rootView: RootView(session: productAccountSession) { launchSnapshot in |
There was a problem hiding this comment.
Run the production budget with Release optimization
The new live RootView/AccountView timings are still executed by the scheme's TestAction, whose build configuration is Debug; the project sets that configuration to SWIFT_OPTIMIZATION_LEVEL = -Onone, while the repository's prescribed xcodebuild test command does not override it. As a result, these asserted launch and mailbox-switch budgets measure an unoptimized, DEBUG-conditional app rather than the production binary named by the test and commit, so the thresholds can produce misleading release conclusions. Use a Release-configured test plan or explicitly pass the Release configuration for this budget.
AGENTS.md reference: AGENTS.md:L126-L129
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Blocked in this automation run: the gipity-bot GitHub App can push code but GitHub rejected the required .github/workflows/ci.yml update because its token lacks workflow scope. I left this thread unresolved; a bot or maintainer with workflow-write permission must add the Release-configured budget invocation.
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift (2)
1576-1583: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winGuard the launch completion hook.
Line 1583 invokes
initialLaunchDidFinish()after multiple awaits without checking cancellation or session freshness. SwiftUI can cancel this task when the view disappears or when the signed-in snapshot changes. Non-throwing operations can still return after cancellation. A stale shell can then satisfy the release measurement.inboxViewModel.refreshPinnedBodyPrefetch(connections: gmailViewModel.connections) + guard !Task.isCancelled, session.isCurrent(snapshot) else { return } initialLaunchDidFinish()As per path instructions, check cancellation and lifecycle transitions in SwiftUI mail-shell code.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift` around lines 1576 - 1583, Guard the launch completion flow around initialLaunchDidFinish() by checking task cancellation and current session/lifecycle freshness after the awaited mailbox synchronization and reload operations. Return or skip the completion hook when the SwiftUI task was cancelled or the signed-in snapshot has changed, while preserving the existing completion behavior for the active session.Source: Path instructions
347-376: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winAdd an identity-token polling regression test.
Change only
identityTokenand assert thatpollWhileActivecontinues polling.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift` around lines 347 - 376, Add a regression test for pollWhileActive that mutates only the session’s identityToken while keeping all other session fields unchanged, then assert polling continues rather than stopping. Reuse the existing polling test setup and counters around pollWhileActive; do not alter production behavior or introduce unrelated session changes.Source: Path instructions
apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift (2)
4532-4550: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winAssert the cached body content before recording the sample.
The
bodyLoadedexpectation only observesonLoaded. It does not verify that the selected message returned"Cached body". A stale cache entry or incorrect message identity can therefore pass the performance gate.Expose the loaded body through the test harness and assert its text and message identity before appending
bodyOpenSamples.As per path instructions, verify externally observable behavior and privacy invariants in tests.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift` around lines 4532 - 4550, Update the body-loading test around MailShellMessageBody and the bodyLoaded expectation to expose the rendered body and associated message identity through the test harness. Before appending to bodyOpenSamples, assert that the loaded content is exactly “Cached body” and belongs to the selected latestMessage, preserving the existing timing measurement only after these checks pass.Source: Path instructions
7571-7580: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRequire the rendered set to contain only current-mailbox IDs.
The helper returns
truewhen any expected ID appears. It does not reject stale IDs or prove that the rendered dataset changed. A stale previous row plus one new row can satisfy this condition.Require a non-empty rendered set that intersects the expected IDs and is a subset of the expected set. Add a stable-frame or completeness check appropriate for the lazy list.
Suggested predicate
for _ in 0..<100 { await releaseRenderFrame(view) - if !driver.renderedItemIds.isDisjoint(with: expectedIdSet) { - return true + let renderedItemIds = driver.renderedItemIds + if !renderedItemIds.isDisjoint(with: expectedIdSet), + renderedItemIds.isSubset(of: expectedIdSet) + { + await releaseRenderFrame(view) + return driver.renderedItemIds.isSubset(of: expectedIdSet) } }As per path instructions, verify externally observable behavior and deterministic isolation in tests.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift` around lines 7571 - 7580, Update releaseWaitForRenderedThreads to require a non-empty renderedItemIds set that intersects expectedIdSet and is entirely contained within it, rejecting stale IDs from other mailboxes. Also add a stable-frame or completeness check appropriate for the lazy list so the helper only returns true after the current rendered dataset has settled, and verify the observable behavior with deterministic test isolation.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift`:
- Around line 4706-4730: Update
testReleaseBudgetDriverIgnoresStaleRendersAfterShellReappears to compare
driver.renderedItemIds, a Set<MailboxThreadIdentity>, against Set([staleId]) and
Set([currentId]) in both XCTAssertEqual assertions.
---
Outside diff comments:
In `@apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift`:
- Around line 1576-1583: Guard the launch completion flow around
initialLaunchDidFinish() by checking task cancellation and current
session/lifecycle freshness after the awaited mailbox synchronization and reload
operations. Return or skip the completion hook when the SwiftUI task was
cancelled or the signed-in snapshot has changed, while preserving the existing
completion behavior for the active session.
- Around line 347-376: Add a regression test for pollWhileActive that mutates
only the session’s identityToken while keeping all other session fields
unchanged, then assert polling continues rather than stopping. Reuse the
existing polling test setup and counters around pollWhileActive; do not alter
production behavior or introduce unrelated session changes.
In `@apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift`:
- Around line 4532-4550: Update the body-loading test around
MailShellMessageBody and the bodyLoaded expectation to expose the rendered body
and associated message identity through the test harness. Before appending to
bodyOpenSamples, assert that the loaded content is exactly “Cached body” and
belongs to the selected latestMessage, preserving the existing timing
measurement only after these checks pass.
- Around line 7571-7580: Update releaseWaitForRenderedThreads to require a
non-empty renderedItemIds set that intersects expectedIdSet and is entirely
contained within it, rejecting stale IDs from other mailboxes. Also add a
stable-frame or completeness check appropriate for the lazy list so the helper
only returns true after the current rendered dataset has settled, and verify the
observable behavior with deterministic test isolation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: ea78af69-d3c3-4a7c-9264-fcb5760b27f2
📒 Files selected for processing (3)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swiftapps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Apple · Unwired Mail
🧰 Additional context used
📓 Path-based instructions (3)
apps/unwired-mail/**/*.{swift,mm,m,h}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands; use
zsh scripts/check-apple-lint.zshfor formatting and linting and the specifiedxcodebuild testcommand for tests.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
SwiftLint runs in strict mode so warnings fail validation; use mise-managed SwiftLint and Xcode's
xcrun swift-formatwhere applicable.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
⚙️ CodeRabbit configuration file
apps/unwired-mail/**/*.swift: Prioritize functional correctness, data protection, and Apple platform
behavior over style already enforced by swift-format and SwiftLint.
Check actor isolation, cancellation, lifecycle transitions, persistence,
retry and offline behavior, and Keychain accessibility. Flag credentials,
tokens, mail content, or decrypted Product Sync data that can be logged,
persisted outside approved device-local storage, or cross a documented
privacy boundary. Require focused tests for changed behavior and failure
paths.
Files:
apps/unwired-mail/unwired-mail/Features/Account/RootView.swiftapps/unwired-mail/unwired-mail/Features/Account/AccountView.swiftapps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
**/*Tests/**/*.swift
⚙️ CodeRabbit configuration file
**/*Tests/**/*.swift: Verify externally observable behavior, privacy invariants, error paths,
cancellation or restart behavior where relevant, and deterministic
isolation. Flag fragile sleeps, ordering dependencies, and tests that
duplicate the implementation instead of exercising it.
Files:
apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift
🔇 Additional comments (4)
apps/unwired-mail/unwired-mail/Features/Account/AccountView.swift (1)
783-797: LGTM!Also applies to: 1017-1042, 1049-1051, 1066-1066, 1084-1100, 1118-1118, 1211-1218, 1424-1426, 1587-1595, 3149-3149, 3202-3202
apps/unwired-mail/unwired-mail/Features/Account/RootView.swift (2)
24-25: 🩺 Stability & AvailabilityConfirm that token-based identity does not reset the mail shell unexpectedly.
ProductAccountSession.revalidateProductAccountAfterForegrounding()can replace the snapshot token while the product account and trusted device remain the same..id(snapshot.identityToken)then tears down and recreatesAccountView, which can cancel mailbox work, reset selection, and rerun launch tasks.Verify that this reset is required. If only account or device changes require recreation, use a stable session identity and update session-dependent state explicitly. Add a foreground revalidation test.
As per path instructions, check lifecycle transitions and cancellation behavior in the Apple app.
Source: Path instructions
3-13: 🎯 Functional CorrectnessNo call-site change is required.
The constrained initializer covers both
RootView(session:)calls. The test suppliessignedInContent, and no caller stores the old concrete type.> Likely an incorrect or invalid review comment.apps/unwired-mail/unwired-mailTests/MailboxConnectionAdapterTests.swift (1)
4303-4359: LGTM!Also applies to: 4361-4385, 4415-4426, 4435-4484, 4590-4617, 8168-8246, 8286-8288
Summary
Validation
The test commands need to be rerun after freeing local disk space. This PR is intentionally a draft.
Closes #176
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.