ADR 0027: Follow-on providers and gated inventory
Status
Accepted
Context
Graph is the MVP mailbox. Architecture still requires a second adapter to prove the port, plus inventory/plan/dry-run contracts so bulk iCloud-to-Microsoft execution can stay a later flag-on milestone. MAIL-20 and MAIL-169 must not delay Synchronization Alpha on Graph. Live Gmail or iCloud OAuth is not required for this decision.
Decision
- Implement Gmail and iCloud against the existing
ProviderAdapterport inpackages/providers. Gmail uses recorded HTTP fixtures and least-privilege scopes (gmail.readonly, thengmail.modify).https://mail.google.com/and send/compose scopes are rejected. iCloud is IMAP inventory only: write methods returnCAPABILITY_NOT_SUPPORTED. - Isolate account worker loops. A Gmail throw cannot halt Graph processing.
- Ship
InventorySource,AnalyzeFolders,CreateMigrationPlan, andRunDryRun. Dry-run never calls adapter writes.StartMigration,PauseMigration, andResumeMigrationreturnPOLICY_DENIEDwhileENABLE_ICLOUD_MIGRATIONis off. Defaults staydry_run_required=trueandsource_delete_allowed=false. ENABLE_SENDandENABLE_DELETEstay false. AI still cannot call adapters.
Alternatives
- Block Graph MVP until live Gmail OAuth exists — rejected; second-provider parity is not an MVP gate.
- Enable StartMigration behind the same flag as inventory — rejected; inventory is read-only, execution is a later milestone.
- Put write methods on iCloud “for later” — rejected; capability flags must deny writes now.
Consequences
Recorded Gmail fixtures and mock IMAP satisfy contract tests. Migration 0019_followon_providers.sql persists plans and dry-run estimates. Live Microsoft connect (ADR 0015) is unchanged. Bulk historical migration remains out of scope.
