Inbox Agent — Synchronization, Event Processing & Reconciliation Specification
Status: Implementation Baseline
Audience: Cursor, Charter, engineering, QA
Purpose: Define reliable ingestion and synchronization of mail provider state into the canonical Inbox Agent model.
1. Goals
Synchronization must produce a complete, convergent local representation of connected mailboxes while tolerating duplicated events, missed notifications, out-of-order delivery, provider throttling, restarts, and partial failures.
The design is provider-adapter based. Provider-specific identifiers and cursors are retained, while downstream application behavior targets the canonical model.
2. Canonical Synchronization Rule
MailMessage represents the logical message/content identity.
MessageInstance represents a provider/account/mailbox-specific occurrence and mutable state of that message.
Synchronization therefore:
- resolves or creates the canonical
MailMessage; - resolves or creates the relevant
MessageInstance; - updates instance-level state without cloning message content;
- records provider identifiers and synchronization metadata;
- emits internal domain events after durable state change.
A message copied, surfaced, or represented in multiple provider contexts may have multiple MessageInstance rows associated with one MailMessage.
3. Provider Adapter Contract
Each provider adapter must expose equivalent capabilities where the provider supports them:
- initial mailbox enumeration;
- incremental change retrieval;
- fetch message metadata/content;
- fetch attachment metadata/content on demand;
- resolve folder/label state;
- write supported state changes;
- cursor/delta-token management;
- provider error normalization;
- webhook/subscription lifecycle where available.
Provider-specific behavior must not leak into domain services except through explicitly modeled capability flags.
4. Initial Synchronization
Initial sync is checkpointed and restartable.
Recommended sequence:
- Register connected account and capabilities.
- Enumerate mailbox/folder/label metadata.
- Establish provider synchronization cursor where possible.
- Backfill messages in bounded pages.
- Canonicalize message identity.
- Upsert MessageInstance state idempotently.
- Queue content/attachment/AI work independently.
- Persist progress checkpoints.
- Run reconciliation before declaring initial sync healthy.
Large mailboxes must not require one transaction or one uninterrupted worker execution.
5. Incremental Synchronization
Incremental sync uses the provider's strongest available change mechanism:
- Provider webhook/push notification when available.
- Delta/history cursor retrieval.
- Scheduled polling as fallback.
Notifications are wake-up hints, not trusted as a complete event log. A notification causes the adapter to read authoritative changes from the provider.
Cursor advancement occurs only after the corresponding changes have been durably processed or safely checkpointed.
6. Idempotency
All synchronization operations must be replay-safe.
Use stable provider keys and unique constraints for:
- account/provider identity;
- provider message/instance identity;
- folder/label membership identity;
- attachment identity;
- event receipt identity when supplied by provider.
Upsert logic must make duplicate webhook delivery and repeated page retrieval harmless.
7. Event Processing
Internal events are produced from committed canonical changes, not directly from raw provider callbacks.
Event envelope should include:
- event ID;
- event type;
- aggregate/entity ID;
- account ID;
- provider;
- source change identifier/cursor when available;
- occurred/observed timestamps;
- schema version;
- correlation/causation IDs;
- retry metadata.
Use transactional outbox semantics, or an equivalent guarantee, so database state and event publication cannot silently diverge.
Consumers must be idempotent.
8. Ordering and Concurrency
Global ordering is not required. Correctness is required at the smallest relevant aggregate boundary.
Concurrency controls must prevent stale processing from overwriting newer state. Appropriate techniques include:
- provider change versions;
- optimistic concurrency/version columns;
- observed provider timestamps;
- serialized work per account/instance when required.
Out-of-order events must converge after reconciliation.
9. Deletions and Missing Items
Provider deletion semantics vary. The local model must distinguish:
- deleted/trashed state;
- instance no longer visible in a mailbox/folder;
- provider hard deletion;
- account disconnection;
- synchronization uncertainty.
Do not delete the canonical MailMessage merely because one MessageInstance disappears. Canonical content may still be referenced by another instance, thread, audit record, or retained metadata.
Physical purging is a separate retention process.
10. Folder and Label Semantics
Folder/label membership is instance/provider state. Adapters normalize provider semantics into canonical mailbox-state structures without pretending all providers behave identically.
The canonical layer must be able to represent:
- zero/one/many folder or label memberships as provider permits;
- inbox/archive/trash/spam-like semantic flags;
- read/unread;
- flagged/starred;
- draft/sent state;
- provider extensions in adapter metadata when no canonical equivalent exists.
11. Write-Back and Echo Suppression
A local mutation follows:
- validate user/policy authorization;
- create a durable mutation request with idempotency key;
- send provider mutation;
- capture provider response;
- observe the change through normal sync;
- reconcile desired vs observed state.
Do not assume API success means final synchronized state.
Locally initiated provider events may be recognized through correlation/idempotency metadata, but they should still be processed. Echo suppression prevents duplicate workflows, not canonical state updates.
12. Retry and Dead-Letter Behavior
Retry transient failures with bounded exponential backoff and jitter. Respect provider retry-after and rate-limit information.
After the configured attempt/window limit:
- move the work item to a failed/dead-letter state;
- preserve diagnostics and payload references;
- surface operational health;
- allow controlled replay.
Poison events must not block the account's entire synchronization stream unless continuing would violate correctness.
13. Reconciliation
Reconciliation is mandatory because notifications and incremental APIs are not assumed perfect.
Reconciliation levels:
- Continuous lightweight: compare recently changed instances and cursor health.
- Periodic mailbox reconciliation: verify counts/identities/state over bounded windows.
- Deep reconciliation: scan provider state against canonical state when drift is detected or manually requested.
Reconciliation detects:
- missing instances;
- orphan local instances;
- stale read/flag/folder state;
- duplicate canonicalization;
- invalid/missing cursors;
- attachment metadata drift;
- failed write-back convergence.
Repairs must be idempotent and auditable.
14. Cursor Recovery
If a provider cursor/delta token expires or becomes invalid:
- mark incremental sync degraded;
- preserve existing canonical data;
- start a bounded resynchronization from the provider-defined recovery point;
- upsert idempotently;
- run reconciliation;
- establish a new cursor.
Cursor loss must not require destructive database reset.
15. Observability
Per connected account track at minimum:
- last successful sync;
- last notification received;
- current cursor/checkpoint;
- sync lag;
- pages/items processed;
- create/update/delete counts;
- duplicate/replay counts;
- retries/failures;
- reconciliation drift and repairs;
- rate-limit/throttle state;
- write-back convergence failures.
Logs must carry account, correlation, and work-item identifiers without exposing message bodies by default.
16. Security
Provider tokens are encrypted and least-privilege scoped. Raw webhook requests are authenticated/validated according to provider requirements.
Message content and attachments are not written to operational logs. Error diagnostics use identifiers and sanitized metadata.
17. Acceptance Criteria
Synchronization is implementation-ready when:
- initial and incremental sync are restartable;
- provider notifications are treated as hints;
- all consumers and upserts are idempotent;
- cursor advancement is safe;
- MailMessage and MessageInstance responsibilities are preserved;
- transactional state/event consistency is addressed;
- write-back converges through normal synchronization;
- reconciliation can detect and repair drift;
- cursor expiration has a non-destructive recovery path;
- account-level health and lag are observable.
