Repository navigation
Adopt SwiftMail 1.10.0 experimentally - #426
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 13 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughSummary
Validation
WalkthroughSwiftMail 1.10.0 and swift-nio-imap 0.4.0 are integrated behind an experimental ChangesSwiftMail engine adoption
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant ExperimentalSwiftMailEngine
participant IMAP
participant SMTP
ExperimentalSwiftMailEngine->>IMAP: connect and authenticate
ExperimentalSwiftMailEngine->>SMTP: connect and authenticate
IMAP-->>ExperimentalSwiftMailEngine: capabilities and mailboxes
SMTP-->>ExperimentalSwiftMailEngine: authenticated transport
ExperimentalSwiftMailEngine-->>ExperimentalSwiftMailEngine: create snapshot and session
Possibly related issues
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
|
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 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.xcodeproj/project.pbxproj`:
- Around line 119-121: Update the unwired-mailTests target configuration to
explicitly include the SwiftMail package product in its package dependencies and
Frameworks build phase. Use the existing SwiftMail product reference and ensure
ExperimentalSwiftMailEngineTests.swift resolves the module through the test
target, without relying on the host application’s dependency.
In
`@apps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift`:
- Around line 56-63: The MailEngineConnectionSnapshot construction currently
reports configuration.minimumTLSVersion as negotiated transport security. Update
the surrounding Swift mail connection flow to capture the actual negotiated TLS
versions for IMAP and SMTP using a supported mechanism, or rename/redefine
transportSecurity to represent minimum TLS versions; do not populate it with the
configured floor while retaining negotiated semantics.
- Around line 119-133: Update capabilities to compare exact capability names via
NIOIMAPCore.Capability.name rather than substring matching, preserving the
existing capability mappings and special-use mailbox check. Ensure XMOVE and
NOMOVE do not enable .move, and add regression coverage for both tokens.
- Around line 234-243: Update appendToSent to avoid converting rawMessage to
UTF-8 before the IMAP append; use the supported SwiftMail API or adapter that
accepts the original Data bytes, preserving existing mailbox and error behavior.
Add a focused test covering a non-UTF-8 MIME message and verifying it is
appended to Sent successfully.
- Around line 462-464: Update the UIDPLUS capability check in the surrounding
mail move flow to match capability tokens by exact equality rather than
substring containment, so values such as X-UIDPLUS are not accepted. Add a
near-match capability test covering X-UIDPLUS and preserve the existing UIDPLUS
behavior only for the exact token.
In `@apps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swift`:
- Around line 6-79: Extend ExperimentalSwiftMailEngineTests with the ADR-0027
MailEngineQualificationCandidateFactory and invoke the unchanged reusable
MailEngineQualificationTests contract. Add focused tests for
SwiftMailEngineSession.validatePage boundary failures, mapping rejection of nil
CopyUID, metadata rejection of missing or zero UIDs,
ExperimentalSwiftMailEngine.connectionError and
SwiftMailEngineSession.mutationError transport-to-operationOutcomeUnknown
mappings, and ExperimentalSwiftMailEngine.capabilities parsing.
In `@docs/adr/0027-qualified-third-party-mail-protocol-engine.md`:
- Line 11: Rename the enclosing ADR heading currently labeled “Candidate
decision” to “Decision” or “Engine decision” so it reflects the accepted
SwiftMail selection. Keep the existing rejected-alternative text and decision
paragraph unchanged.
In `@docs/qualification/swiftmail-experimental-engine.md`:
- Around line 16-18: The documentation must align with ADR-0027’s move
acceptance gate: update the paragraph describing COPYUID, UIDPLUS, and MOVE to
state that advertised MOVE remains supported without UIDPLUS, or explicitly
document the amended ADR decision and rationale if the engine behavior remains
unchanged. Verify the wording against ExperimentalSwiftMailEngine.move and
ADR-0027 so the documented product behavior is consistent.
- Around line 45-53: Update the Apple lint command documentation in this guide
and README.md to use consistent conditional wording, clearly stating when the
mise-managed `mise exec -- zsh scripts/check-apple-lint.zsh` form is required or
accepted. Preserve the existing test command and reference the linked runbook
for the prerequisite details.
🪄 Autofix
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: 44f8362c-7e7d-4217-8902-010df3fd5cea
⛔ Files ignored due to path filters (1)
apps/unwired-mail/unwired-mail.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolvedis excluded by!**/Package.resolved
📒 Files selected for processing (6)
README.mdapps/unwired-mail/unwired-mail.xcodeproj/project.pbxprojapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swiftapps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftdocs/adr/0027-qualified-third-party-mail-protocol-engine.mddocs/qualification/swiftmail-experimental-engine.md
📜 Review details
🧰 Additional context used
📓 Path-based instructions (6)
apps/unwired-mail/**/*.{swift,m,mm}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands. Run
zsh scripts/check-apple-lint.zshfor format and lint, and use the documentedxcodebuild testcommand for tests; SwiftLint runs in strict mode.
Files:
apps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Apple validation must use SwiftLint strict mode and Swift Format strict linting; if Apple tooling is unavailable, report that clearly in the final handoff.
Files:
apps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.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-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.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/ExperimentalSwiftMailEngineTests.swift
docs/adr/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Record durable architecture decisions and privacy-boundary decisions in
docs/adr/.
Files:
docs/adr/0027-qualified-third-party-mail-protocol-engine.md
**/*.md
⚙️ CodeRabbit configuration file
**/*.md: Treat docs as product truth, not marketing. Prefer precise domain language
from CONTEXT.md; flag undefined terms, synonym drift, and conflicts with
existing ADRs under docs/adr/. For ADR changes, require a clear decision,
consequences, and privacy or security boundary impact; flag silent
reversals of prior ADRs without an explicit supersession note. For
docs/agents/ and bootstrap docs, verify agent workflow, validation, and
triage guidance stay aligned with AGENTS.md. Flag broken cross-links,
speculative future claims presented as shipped behavior, and docs that
omit the Apple vs TypeScript ownership of a boundary they describe.
Files:
docs/adr/0027-qualified-third-party-mail-protocol-engine.mdREADME.mddocs/qualification/swiftmail-experimental-engine.md
README.md
📄 CodeRabbit inference engine (AGENTS.md)
Update
README.mdwhen developer setup, common commands, or high-level project navigation changes.
Files:
README.md
🔇 Additional comments (11)
apps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift (8)
6-21: LGTM!
154-195: LGTM!
262-292: LGTM!
294-315: LGTM!
512-568: LGTM!Also applies to: 570-659
380-391: 🚀 Performance & Scalability
492-494: 🗄️ Data Integrity & IntegrationKeep the cancellation classification
SwiftMail wraps every failure after
MAIL FROMdispatch inSMTPSendError. A bareCancellationErrorcan only occur before the SMTP dialogue starts, so.notSubmitted(.transportUnavailable)is safe here.> Likely an incorrect or invalid review comment.
335-352: 🩺 Stability & AvailabilityDefine the empty refresh signal.
MailEngineIdleEventdoes not document whether.changedUIDs([])means “mailbox changed; re-scan.” Add an explicit contract and focused tests for.existsand.expungewith unchanged UIDVALIDITY, or use a distinct event.README.md (1)
171-171: LGTM!apps/unwired-mail/unwired-mail.xcodeproj/project.pbxproj (1)
784-791: 📐 Maintainability & Code QualityKeep the checked-in SwiftPM lockfile.
Package.resolvedis tracked and records SwiftMail1.10.0at revisionc907f871bb23812895274f4c7ae17bf343171c1e, matchingSwiftMailExperimentalBuildPolicy.dependencyRevision.> Likely an incorrect or invalid review comment.apps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swift (1)
22-31: 📐 Maintainability & Code QualityDo not raise this concern. SwiftMail 1.10.0 declares both initializers as
publicat the pinned commit.> Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/qualification/swiftmail-experimental-engine.md (2)
1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winUse the product term “Experimental Mail Engine”.
The heading uses “Experimental SwiftMail engine”. Use “Experimental Mail Engine” for the implementation and reserve “SwiftMail” for the dependency. Use “Standards-Based Mailbox Connection” when the document refers to the account boundary.
As per path instructions: “Prefer precise domain language from CONTEXT.md; flag undefined terms, synonym drift, and conflicts with existing ADRs under docs/adr/.”
🤖 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 `@docs/qualification/swiftmail-experimental-engine.md` at line 1, Update the document heading and terminology to use “Experimental Mail Engine” for the implementation, reserve “SwiftMail” for the dependency, and use “Standards-Based Mailbox Connection” for the account boundary. Check the document for synonym drift and align terms with CONTEXT.md and relevant ADRs.Source: Path instructions
39-45: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winAdd an exact SwiftMail pin check.
xcodebuild -resolvePackageDependenciesresolves dependencies but does not assert SwiftMail version1.10.0and revisionc907f871bb23812895274f4c7ae17bf343171c1e. Add a check that readsPackage.resolvedand fails when either value differs.🤖 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 `@docs/qualification/swiftmail-experimental-engine.md` around lines 39 - 45, Extend the dependency verification instructions after the xcodebuild command to read Package.resolved and assert SwiftMail is exactly version 1.10.0 at revision c907f871bb23812895274f4c7ae17bf343171c1e. Make the check fail when either value differs, while retaining the existing package-resolution step.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/MailEngineQualificationTests.swift`:
- Around line 2873-2874: Update the second minimumTLSVersions expectation in the
qualification test to match the .tls12 default copied by
snapshot(configuration:) for both connections, unless intentionally changing the
snapshot contract; if changing it, update the fixture and
ExperimentalSwiftMailEngine consistently to represent negotiated TLS.
In `@docs/adr/0027-qualified-third-party-mail-protocol-engine.md`:
- Around line 9-11: Update the Decision section to state that SwiftMail 1.10.0
is the adopted and integrated Experimental Mail Engine, rather than a preferred
candidate. Replace the production-default wording with the precise boundary that
Standards-Based Mailbox Connections are not enabled in externally distributed
Release builds until the required vertical spikes and certification are
complete, and explicitly record the resulting privacy/security boundary.
---
Outside diff comments:
In `@docs/qualification/swiftmail-experimental-engine.md`:
- Line 1: Update the document heading and terminology to use “Experimental Mail
Engine” for the implementation, reserve “SwiftMail” for the dependency, and use
“Standards-Based Mailbox Connection” for the account boundary. Check the
document for synonym drift and align terms with CONTEXT.md and relevant ADRs.
- Around line 39-45: Extend the dependency verification instructions after the
xcodebuild command to read Package.resolved and assert SwiftMail is exactly
version 1.10.0 at revision c907f871bb23812895274f4c7ae17bf343171c1e. Make the
check fail when either value differs, while retaining the existing
package-resolution step.
🪄 Autofix
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: 884e5090-0462-4e67-ac6f-db12638f26a5
📒 Files selected for processing (8)
README.mdapps/unwired-mail/unwired-mail.xcodeproj/project.pbxprojapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/MailEngine.swiftapps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swiftdocs/adr/0027-qualified-third-party-mail-protocol-engine.mddocs/qualification/swiftmail-experimental-engine.md
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
- GitHub Check: Apple Debug · Unwired Mail
- GitHub Check: Apple performance · Unwired Mail
🧰 Additional context used
📓 Path-based instructions (6)
**/*.md
⚙️ CodeRabbit configuration file
**/*.md: Treat docs as product truth, not marketing. Prefer precise domain language
from CONTEXT.md; flag undefined terms, synonym drift, and conflicts with
existing ADRs under docs/adr/. For ADR changes, require a clear decision,
consequences, and privacy or security boundary impact; flag silent
reversals of prior ADRs without an explicit supersession note. For
docs/agents/ and bootstrap docs, verify agent workflow, validation, and
triage guidance stay aligned with AGENTS.md. Flag broken cross-links,
speculative future claims presented as shipped behavior, and docs that
omit the Apple vs TypeScript ownership of a boundary they describe.
Files:
docs/qualification/swiftmail-experimental-engine.mdREADME.mddocs/adr/0027-qualified-third-party-mail-protocol-engine.md
apps/unwired-mail/**/*.{swift,m,mm}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands. Run
zsh scripts/check-apple-lint.zshfor format and lint, and use the documentedxcodebuild testcommand for tests; SwiftLint runs in strict mode.
Files:
apps/unwired-mail/unwired-mail/Services/Mailbox/MailEngine.swiftapps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Apple validation must use SwiftLint strict mode and Swift Format strict linting; if Apple tooling is unavailable, report that clearly in the final handoff.
Files:
apps/unwired-mail/unwired-mail/Services/Mailbox/MailEngine.swiftapps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.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/Services/Mailbox/MailEngine.swiftapps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swiftapps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.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/ExperimentalSwiftMailEngineTests.swiftapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swift
README.md
📄 CodeRabbit inference engine (AGENTS.md)
Update
README.mdwhen developer setup, common commands, or high-level project navigation changes.
Files:
README.md
docs/adr/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Record durable architecture decisions and privacy-boundary decisions in
docs/adr/.
Files:
docs/adr/0027-qualified-third-party-mail-protocol-engine.md
🔇 Additional comments (12)
apps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift (3)
119-131: UseCapability.namebefore exact matching.
String(describing:)does not use the protocol token API.Capability.nameis the public parser for the capability name. The current conversion can produce a reflected struct description, soIDLE,MOVE, andUIDPLUSare not detected even when the server advertises them. (raw.githubusercontent.com)Keep the exact comparisons. Change the input conversion to
$0.name.uppercased(). Add an integration-level regression test that passes realCapabilityvalues.#!/bin/bash set -euo pipefail rg -n -C 6 'fetchCapabilities\(\)|String\(describing: \$0\)|Capability\.name|capabilities\(' \ apps/unwired-mail/unwired-mail/Services/Mailbox/ExperimentalSwiftMailEngine.swift \ apps/unwired-mail/unwired-mailTests --glob '*.swift'
228-260: Append the original message bytes to Sent.
appendToSentrejects non-UTF-8 bytes before IMAP APPEND. SMTP can already accept those exact bytes. The Sent-copy recovery path then fails without a valid reason.Use a byte-preserving APPEND API or adapter. Add a non-UTF-8 MIME regression test.
23-117: LGTM!Also applies to: 172-196, 294-698
apps/unwired-mail/unwired-mail.xcodeproj/project.pbxproj (2)
119-122: LGTM!Also applies to: 270-271, 294-303, 369-369, 438-438, 503-525, 675-675, 729-729, 805-814
789-795: 📐 Maintainability & Code QualityNo change required.
Package.resolvedis tracked and records SwiftMail1.10.0at revisionc907f871bb23812895274f4c7ae17bf343171c1e.apps/unwired-mail/unwired-mail/Services/Mailbox/MailEngine.swift (1)
98-104: LGTM!README.md (1)
166-173: LGTM!apps/unwired-mail/unwired-mailTests/ExperimentalSwiftMailEngineTests.swift (2)
6-18: Wire this suite to the reusable qualification contract.This file still declares no
MailEngineQualificationCandidateFactoryand never invokesMailEngineQualificationContractfromMailEngineQualificationTests.swift. The added tests cover helper functions, but they do not run the reusable TLS, cancellation, UID-mapping, SMTP, and privacy checks for this candidate. Add the factory and contract invocation, or identify the target file that owns this wiring.As per path instructions: “Require focused tests for changed behavior and failure paths.”
Source: Path instructions
20-46: LGTM!Also applies to: 48-78, 80-94, 96-107, 109-136, 138-148
docs/qualification/swiftmail-experimental-engine.md (2)
16-20: Keep the ADR-0027 gate in the release condition.Lines 16-20 state that the candidate does not satisfy ADR-0027’s MOVE-without-UIDPLUS production gate. Lines 26-35 name only issue
#280certification before production enablement. Add the ADR gate to the release condition, or implement the missing path or explicitly supersede the ADR. Provider certification alone must not enable a candidate that this document records as outside the production acceptance gate.As per path instructions: “Flag conflicts with existing ADRs under docs/adr/.”
Also applies to: 26-35
Source: Path instructions
3-10: LGTM!Also applies to: 12-15, 21-24, 47-59
apps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swift (1)
360-375: LGTM!Also applies to: 438-439, 519-519, 6379-6379, 6525-6526, 6566-6569
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/MailEngineQualificationTests.swift (1)
438-440: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick winAssert the configured TLS values exactly.
MailEngineConnectionSnapshotnow exposes configured minimum TLS versions. The helper only checks that both service keys exist and that each value is at least.tls12. A candidate can report.tls12for a.tls13configuration and still pass. Compare the map with the expected configuration and add a successful.tls13case when the fixture supports it.As per path instructions, tests must verify externally observable behavior and relevant failure paths.
🤖 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/MailEngineQualificationTests.swift` around lines 438 - 440, Update the snapshot assertions in the relevant MailEngine qualification test to compare minimumTLSVersions against the exact expected IMAP and SMTP TLS configuration, rather than only checking keys and a lower bound. Add a successful TLS 1.3 configuration case when supported by the fixture, while preserving coverage of the existing TLS 1.2 behavior and relevant failure paths.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/MailEngineQualificationTests.swift`:
- Around line 438-440: Update the snapshot assertions in the relevant MailEngine
qualification test to compare minimumTLSVersions against the exact expected IMAP
and SMTP TLS configuration, rather than only checking keys and a lower bound.
Add a successful TLS 1.3 configuration case when supported by the fixture, while
preserving coverage of the existing TLS 1.2 behavior and relevant failure paths.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 53bc8cd3-1c4f-4e08-b56d-0a3abcf0e1c5
📒 Files selected for processing (3)
apps/unwired-mail/unwired-mail.xcodeproj/project.pbxprojapps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swiftdocs/adr/0027-qualified-third-party-mail-protocol-engine.md
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: Apple Debug · Unwired Mail
🧰 Additional context used
📓 Path-based instructions (5)
docs/adr/**/*
📄 CodeRabbit inference engine (AGENTS.md)
Record durable architecture decisions and privacy-boundary decisions in
docs/adr/.
Files:
docs/adr/0027-qualified-third-party-mail-protocol-engine.md
**/*.md
⚙️ CodeRabbit configuration file
**/*.md: Treat docs as product truth, not marketing. Prefer precise domain language
from CONTEXT.md; flag undefined terms, synonym drift, and conflicts with
existing ADRs under docs/adr/. For ADR changes, require a clear decision,
consequences, and privacy or security boundary impact; flag silent
reversals of prior ADRs without an explicit supersession note. For
docs/agents/ and bootstrap docs, verify agent workflow, validation, and
triage guidance stay aligned with AGENTS.md. Flag broken cross-links,
speculative future claims presented as shipped behavior, and docs that
omit the Apple vs TypeScript ownership of a boundary they describe.
Files:
docs/adr/0027-qualified-third-party-mail-protocol-engine.md
apps/unwired-mail/**/*.{swift,m,mm}
📄 CodeRabbit inference engine (AGENTS.md)
The Apple app must provide formatter, linter, and test commands. Run
zsh scripts/check-apple-lint.zshfor format and lint, and use the documentedxcodebuild testcommand for tests; SwiftLint runs in strict mode.
Files:
apps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swift
apps/unwired-mail/**/*.swift
📄 CodeRabbit inference engine (AGENTS.md)
Apple validation must use SwiftLint strict mode and Swift Format strict linting; if Apple tooling is unavailable, report that clearly in the final handoff.
Files:
apps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.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-mailTests/MailEngineQualificationTests.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/MailEngineQualificationTests.swift
🔇 Additional comments (4)
docs/adr/0027-qualified-third-party-mail-protocol-engine.md (2)
11-11: Align the remaining ADR language with the adopted state.Line 11 correctly adopts SwiftMail 1.10.0 for experimental and internal use and gates externally distributed Release builds. Line 17 still says “by default in a production release”, and Line 44 still says the façade exists “before any candidate dependency is adopted”. Replace both phrases with the adopted Experimental Mail Engine and externally distributed Release terminology.
As per path instructions, docs are product truth and must use precise domain language without synonym drift.
Source: Path instructions
9-9: LGTM!Also applies to: 45-45
apps/unwired-mail/unwired-mail.xcodeproj/project.pbxproj (1)
119-124: LGTM!Also applies to: 272-273, 296-297, 306-307, 373-373, 442-442, 508-508, 530-531, 589-589, 682-682, 736-736, 796-811, 820-839
apps/unwired-mail/unwired-mailTests/MailEngineQualificationTests.swift (1)
360-375: LGTM!Also applies to: 519-519, 2873-2874, 6356-6366, 6379-6379, 6525-6526, 6566-6569
Summary
c907f871bb23812895274f4c7ae17bf343171c1eMailEngineimplementation for TLS/authentication, metadata paging, body-part fetches, IDLE, safe UID copy/move, Sent append, and SMTP outcome classificationValidation
mise exec -- zsh scripts/check-apple-lint.zshExperimentalSwiftMailEngineTestson iPhone 17 simulatorD6D43A14-3B1A-41B6-B25A-0DFCA1BFB089TESTING CI_PERFORMANCE_BUDGETplutil -lint apps/unwired-mail/unwired-mail.xcodeproj/project.pbxprojgit diff --checkAll commands passed. Xcode emitted existing Swift 6 concurrency and unused-result warnings outside this change.
Remaining human actions
No human action is required before this experimental change can merge or issue #178 can close. The protected iCloud Mail and Fastmail certification tracked in #280 must still be completed before SwiftMail can be enabled in an externally distributed Release build.
Closes #178
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.