Inbox Agent Canonical Data Model and Entity Relationship Specification
1. Purpose
This document defines the canonical relational data model for the Inbox Agent platform.
It consolidates the entities referenced across the functional, technical architecture, migration, learning, and UI specifications into one normalized model.
The purpose is to ensure that implementation planning does not create overlapping or contradictory storage structures.
This document defines:
- Core entities
- Entity responsibilities
- Primary relationships
- Ownership boundaries
- Suggested keys
- Important attributes
- Normalization rules
- Historical/provenance requirements
- Extension points for future contacts and native-client functionality
This is not intended to be final physical DDL.
It is the authoritative logical model from which implementation-specific schemas may be derived.
2. Data Modeling Principles
The canonical model should follow these principles:
RELATIONAL CORE
PROVIDER-INDEPENDENT DOMAIN MODEL
EXPLICIT OWNERSHIP
NORMALIZED PRIMARY ENTITIES
PROVENANCE PRESERVED
AUDIT APPEND-ORIENTED
SOFT STATE SEPARATED FROM PROVIDER STATE
HISTORICAL DATA DISTINGUISHED FROM ACTIVE WORK
RULES STORED AS DATA, NOT EXECUTABLE CODE
3. Core Domain Areas
The model should be organized into the following domains:
Identity and Ownership
Mail Provider Integration
Mail Content
Conversation State
Classification and Attention
Rules and Learning
Approvals and Commands
Migration
Audit and Observability
Projects and Context
Future Contacts
4. High-Level Entity Relationships
Conceptual relationship map:
User
│
├── MailAccount
│ │
│ ├── MailIdentity
│ ├── ProviderConnection
│ ├── MailFolder
│ ├── Message
│ │ │
│ │ ├── MessageRecipient
│ │ ├── Attachment
│ │ ├── MessageClassification
│ │ ├── UserCorrection
│ │ └── AuditEvent
│ │
│ └── ProviderSyncState
│
├── Conversation
│ ├── Messages
│ ├── ConversationState
│ └── WaitingState
│
├── Rule
│ ├── RuleCondition
│ ├── RuleAction
│ ├── RuleVersion
│ └── RuleExecution
│
├── LearnedPreference
├── RuleSuggestion
├── Approval
├── MailCommand
├── Project
├── SenderProfile
└── MigrationRun
└── MigrationItem
5. User
Entity:
User
Purpose:
Represents the owner of the Inbox Agent environment.
Although the initial product is single-user, the model should include ownership explicitly.
Suggested fields:
id
display_name
primary_email_optional
timezone
status
created_at
updated_at
Initial relationship:
User 1 ─── N MailAccount
User 1 ─── N Rule
User 1 ─── N Approval
User 1 ─── N Project
6. MailAccount
Entity:
MailAccount
Represents one physical provider mailbox.
Examples:
jskoch@msn.com
jason@jasonkoch.io
Jason.s.koch@gmail.com
platypus.software.dev@gmail.com
jskoch67@icloud.com
Jason.s.koch@icloud.com
Suggested fields:
id
user_id
provider_type
provider_account_identifier
primary_address
display_name
mailbox_type
status
operating_mode
is_historical
created_at
updated_at
Possible provider_type values:
MICROSOFT
GMAIL
ICLOUD
OTHER
Possible mailbox_type values:
PERSONAL
PROFESSIONAL
COMMERCIAL
SYSTEM_SERVICE
APPLE_INFRASTRUCTURE
LEGACY
Possible operating_mode values:
ACTIVE
FORWARDING
READ_ONLY
MIGRATING
LEGACY
RETIRED_FROM_MAIL
7. MailIdentity
Entity:
MailIdentity
Represents an email identity associated with a physical mailbox.
A mailbox may have multiple identities.
Example:
MailAccount:
jason@jasonkoch.io
MailIdentities:
jason@jasonkoch.io
jason@jasonkoch.ai
Suggested fields:
id
mail_account_id
email_address
identity_type
purpose
is_primary
is_alias
is_active
created_at
updated_at
Possible identity_type:
PRIMARY
ALIAS
FORWARDED
LEGACY
8. ProviderConnection
Entity:
ProviderConnection
Represents authorization and connectivity state for one physical mailbox.
Sensitive secrets should not necessarily reside directly in this table.
Suggested fields:
id
mail_account_id
provider_type
authorization_type
authorization_status
credential_reference
granted_scopes
connected_at
last_token_refresh_at
last_authorization_error_at
created_at
updated_at
credential_reference should point to secure encrypted secret storage rather than expose tokens directly.
9. ProviderCapability
Optional entity:
ProviderCapability
May be modeled as normalized rows or capability metadata.
Purpose:
Captures what operations a provider connection supports.
Examples:
READ
MODIFY
MOVE
ARCHIVE
CATEGORIES
LABELS
DRAFT
SEND
RULES
PUSH_NOTIFICATIONS
DELTA_SYNC
THREADS
Suggested fields:
provider_connection_id
capability_code
enabled
source
last_verified_at
10. MailFolder
Entity:
MailFolder
Represents provider-native folders or Gmail label-equivalent containers where appropriate.
Suggested fields:
id
mail_account_id
provider_folder_id
parent_folder_id
name
full_path
folder_type
is_system
is_active
message_count_cached
unread_count_cached
created_at
updated_at
Possible folder_type:
INBOX
SENT
DRAFTS
ARCHIVE
JUNK
DELETED
USER
LABEL
OTHER
11. FolderMapping
Entity:
FolderMapping
Used primarily for rationalization and migration.
Suggested fields:
id
mail_folder_id
semantic_role
disposition
target_mail_account_id
target_folder_id
confidence
review_status
reviewed_at
created_at
updated_at
Possible disposition:
KEEP
MERGE
RENAME
ARCHIVE_AS_IS
CONVERT_TO_VIEW
MOVE_CONTENT_ONLY
DELETE_EMPTY
REVIEW
12. Message
Entity:
Message
Represents the application's canonical record of an email message.
Suggested fields:
id
mail_account_id
conversation_id
provider_message_id
provider_immutable_id
provider_thread_id
internet_message_id
subject
normalized_subject
sender_address
sender_name
sent_at
received_at
body_preview
body_storage_state
has_attachments
is_read
is_draft
is_historical
current_folder_id
delivered_identity_id
migration_run_id
created_at
updated_at
Important:
Message.id
is the application's canonical identifier.
It must not depend solely on a mutable provider message ID.
13. Message Body Storage
The logical model should support body-storage metadata without requiring full persistent body duplication.
Suggested fields or related entity:
body_storage_state
body_cache_reference
body_cached_at
body_cache_expires_at
Possible states:
PROVIDER_ONLY
TEMPORARILY_CACHED
PERSISTED_FOR_MIGRATION
PERSISTED_BY_POLICY
14. MessageRecipient
Entity:
MessageRecipient
Normalized recipient storage avoids embedding recipient lists in JSON.
Suggested fields:
id
message_id
recipient_type
email_address
display_name
mail_identity_id_optional
sequence
Possible recipient_type:
TO
CC
BCC
REPLY_TO
This is important for:
Alias detection
Original recipient tracking
Search
Conversation analysis
15. MessageHeader
Optional entity:
MessageHeader
Used when selected raw transport headers need preservation.
Suggested fields:
id
message_id
header_name
header_value
Not every provider header needs to be stored permanently.
Only useful headers should be persisted.
16. Attachment
Entity:
Attachment
Suggested fields:
id
message_id
provider_attachment_id
filename
mime_type
size_bytes
content_hash_optional
is_inline
content_reference
metadata_status
created_at
Full attachment content should remain provider-hosted by default unless required.
17. Conversation
Entity:
Conversation
Represents the application's provider-independent logical thread.
Suggested fields:
id
user_id
normalized_subject
current_attention_state
current_priority
primary_classification
status
last_message_at
last_human_message_at
last_user_message_at
resolved_at
created_at
updated_at
Conversation should be the primary unit for:
RESPOND
WAITING
ACTION
RESOLUTION
where possible.
18. ConversationParticipant
Entity:
ConversationParticipant
Suggested fields:
id
conversation_id
email_address
display_name
mail_identity_id_optional
sender_profile_id_optional
participant_role
first_seen_at
last_seen_at
19. MessageClassification
Entity:
MessageClassification
Represents semantic interpretation of a message.
Suggested fields:
id
message_id
primary_classification
attention_state
priority
retention_state
requires_action
requires_response
project_id
vendor_name
confidence_level
classification_source
classifier_version
classified_at
superseded_at
Possible classification sources:
RULE
AI
USER
MIGRATION
SYSTEM
20. ClassificationTag
Entity:
ClassificationTag
For secondary semantic labels.
Suggested fields:
id
message_id
tag_code
source
confidence
created_at
Examples:
FINANCIAL
TRAVEL
PURCHASE
SECURITY
FAMILY
PROJECT
A message may have multiple tags.
21. Attention State
Attention state should be represented as an enumerated domain.
Initial values:
UNPROCESSED
ACTION
RESPOND
WAITING
READ_LATER
REFERENCE
SYSTEM_ALERT
ARCHIVE
DISCARD_CANDIDATE
The current conversation-level state may live directly on Conversation.
Message-level historical evaluations may remain in MessageClassification.
22. Priority
Priority domain:
CRITICAL
HIGH
NORMAL
LOW
BACKGROUND
Priority and attention state are independent.
23. Retention State
Retention domain:
PERMANENT
LONG_TERM
STANDARD
TEMPORARY
DISCARD_CANDIDATE
Retention should not be inferred directly from whether something is archived.
24. ConversationActionState
Optional entity:
ConversationActionState
Useful if action metadata grows beyond simple conversation fields.
Suggested fields:
conversation_id
action_summary
due_at
snoozed_until
completed_at
completion_source
updated_at
25. WaitingState
Entity:
WaitingState
Suggested fields:
id
conversation_id
waiting_on_address
waiting_on_name
reason
started_at
expected_response_at
follow_up_after
status
resolved_at
created_at
updated_at
Possible status:
ACTIVE
RESPONDED
RESOLVED
DISMISSED
OVERDUE
26. SenderProfile
Entity:
SenderProfile
Represents accumulated contextual knowledge about a sender or domain.
Suggested fields:
id
user_id
email_address
domain
display_name
sender_type
relationship_type
is_known_human
is_vip
typical_classification
typical_priority
preferred_identity_id
automation_profile
created_at
updated_at
Possible sender types:
PERSON
COMPANY
SYSTEM
MARKETING
NEWSLETTER
UNKNOWN
27. LearnedPreference
Entity:
LearnedPreference
Represents soft preference signals that influence AI reasoning but do not deterministically execute actions.
Suggested fields:
id
user_id
preference_type
scope_type
scope_value
preferred_value
confidence
source
active
created_at
updated_at
Examples:
Jane usually HIGH priority
Newsletter X usually READ_LATER
Vendor Y typically FINANCIAL
28. UserCorrection
Entity:
UserCorrection
Suggested fields:
id
user_id
message_id
conversation_id
field_name
previous_value
corrected_value
reason
created_at
Corrections should remain immutable historical records.
29. PatternObservation
Optional entity:
PatternObservation
Represents structured recurring behavior detected by the learning system.
Suggested fields:
id
user_id
pattern_type
scope_type
scope_value
sample_count
match_count
exception_count
consistency_rate
first_observed_at
last_observed_at
status
30. RuleSuggestion
Entity:
RuleSuggestion
Represents an agent-proposed automation that is not yet active.
Suggested fields:
id
user_id
pattern_observation_id
suggested_name
suggested_scope
suggested_action_summary
confidence
estimated_monthly_matches
risk_level
status
created_at
reviewed_at
Possible status:
PENDING
APPROVED
MODIFIED
REJECTED
SUPPRESSED
EXPIRED
31. Rule
Entity:
Rule
Represents an approved deterministic automation definition.
Suggested fields:
id
user_id
name
description
rule_origin
scope_type
scope_value
execution_mode
priority
status
risk_level
current_version_id
created_at
updated_at
Possible origin:
USER_DEFINED
AGENT_SUGGESTED
SYSTEM_DEFAULT
MIGRATED_PROVIDER_RULE
32. RuleVersion
Entity:
RuleVersion
Rules should be versioned.
Suggested fields:
id
rule_id
version_number
change_summary
created_by
created_at
A rule execution should reference a specific version.
33. RuleCondition
Entity:
RuleCondition
Suggested fields:
id
rule_version_id
condition_group
field_name
operator
comparison_value
sequence
Compound logic may use:
condition_group
group_operator
to support nested AND/OR logic.
34. RuleAction
Entity:
RuleAction
Suggested fields:
id
rule_version_id
action_type
action_value
risk_level
sequence
Examples:
SET_CLASSIFICATION
SET_PRIORITY
SET_ATTENTION
ARCHIVE
MARK_READ
APPLY_LABEL
ASSIGN_PROJECT
35. RuleExecution
Entity:
RuleExecution
Suggested fields:
id
rule_id
rule_version_id
message_id
conversation_id
execution_status
matched_at
executed_at
action_count
correlation_id
undo_requested
error_code
This supports rule-health analysis.
36. RuleException
Optional entity:
RuleException
Used to track explicit or learned exceptions.
Suggested fields:
id
rule_id
scope_type
scope_value
reason
active
created_at
37. RuleHealthMetric
Optional entity or derived view:
RuleHealthMetric
Possible values:
execution_count
undo_count
correction_count
exception_count
observed_accuracy
last_reviewed_at
health_state
These may be calculated rather than physically stored.
38. Approval
Entity:
Approval
Represents an explicit human authorization request.
Suggested fields:
id
user_id
approval_type
risk_level
requested_by_actor_type
requested_by_reference
payload_summary
affected_item_count
status
requested_at
decided_at
expires_at
decision_reason
Possible status:
PENDING
APPROVED
REJECTED
EXPIRED
CANCELLED
EXECUTED
39. MailCommand
Entity:
MailCommand
Represents a durable requested provider mutation.
Suggested fields:
id
user_id
mail_account_id
message_id
conversation_id
command_type
requested_by_actor
approval_id
status
idempotency_key
correlation_id
created_at
started_at
completed_at
error_code
Possible command types:
MARK_READ
MARK_UNREAD
ARCHIVE
MOVE
SET_CATEGORY
APPLY_LABEL
CREATE_DRAFT
SEND
DELETE
High-risk commands may be prohibited by policy.
40. Draft
Optional entity:
Draft
Recommended if application-generated drafts need independent state.
Suggested fields:
id
conversation_id
mail_account_id
from_identity_id
provider_draft_id
draft_source
body_reference
status
created_at
updated_at
Possible status:
SUGGESTED
SAVED_PROVIDER
EDITED
SENT
DISCARDED
41. DraftRevision
Optional entity:
DraftRevision
Useful for learning draft style.
Suggested fields:
id
draft_id
revision_number
revision_source
change_magnitude
created_at
42. Project
Entity:
Project
Represents contextual work association.
Suggested fields:
id
user_id
name
description
status
created_at
updated_at
Messages and conversations may be assigned to projects independently of folders.
43. ProjectSignal
Optional entity:
ProjectSignal
Can store patterns used to infer project association.
Examples:
Sender domain
Repository name
Vercel project
Subject token
Known participant
44. IdentityRecommendation
Entity:
IdentityRecommendation
Supports Identity Hygiene.
Suggested fields:
id
user_id
sender_profile_id
current_identity_id
recommended_identity_id
message_count
estimated_monthly_volume
reason
confidence
status
created_at
reviewed_at
Possible status:
PENDING
ACCEPTED
REJECTED
SUPPRESSED
CURRENT_IDENTITY_CONFIRMED
45. MigrationRun
Entity:
MigrationRun
Represents one migration batch.
Suggested fields:
id
user_id
source_mail_account_id
target_mail_account_id
run_type
status
dry_run
started_at
completed_at
selected_count
success_count
duplicate_count
conflict_count
failed_count
correlation_id
Possible run types:
INVENTORY
DRY_RUN
PILOT
BULK
RECONCILIATION
CLEANUP
46. MigrationItem
Entity:
MigrationItem
Represents one source message's migration result.
Suggested fields:
id
migration_run_id
source_message_id
source_provider_message_id
source_folder_id
target_message_id
target_provider_message_id
duplicate_status
migration_status
error_code
processed_at
47. DuplicateCandidate
Entity:
DuplicateCandidate
Useful for migration and cleanup.
Suggested fields:
id
message_a_id
message_b_id
match_method
confidence
status
created_at
reviewed_at
Possible status:
UNIQUE
LIKELY_DUPLICATE
CONFIRMED_DUPLICATE
CONFLICT
UNKNOWN
48. SyncCheckpoint
Entity:
SyncCheckpoint
Represents provider synchronization progress.
Suggested fields:
id
mail_account_id
resource_type
checkpoint_type
checkpoint_value
last_successful_sync_at
created_at
updated_at
Examples:
Microsoft delta link
Gmail history ID
IMAP UID checkpoint
49. ProviderSubscription
Entity:
ProviderSubscription
Tracks Graph subscriptions or Gmail watches.
Suggested fields:
id
mail_account_id
subscription_type
provider_subscription_id
resource
status
created_at
expires_at
last_renewed_at
last_notification_at
50. ProcessingJob
Entity:
ProcessingJob
Represents durable background operations.
Suggested fields:
id
job_type
user_id
mail_account_id
related_entity_type
related_entity_id
status
progress_current
progress_total
attempt_count
started_at
completed_at
last_error_code
correlation_id
51. AuditEvent
Entity:
AuditEvent
Append-oriented record of meaningful state changes.
Suggested fields:
id
user_id
timestamp
actor_type
actor_reference
event_type
mail_account_id
message_id
conversation_id
rule_id
approval_id
migration_run_id
old_value
new_value
reason_summary
confidence
correlation_id
reversible
undo_reference
52. Audit Actor Types
Supported actor types:
USER
RULE_ENGINE
AI_AGENT
MIGRATION_ENGINE
SYSTEM
PROVIDER
53. Audit Event Types
Representative events:
MESSAGE_CLASSIFIED
ATTENTION_CHANGED
PRIORITY_CHANGED
MESSAGE_ARCHIVED
MESSAGE_MOVED
RULE_CREATED
RULE_UPDATED
RULE_EXECUTED
RULE_UNDONE
CORRECTION_RECORDED
APPROVAL_GRANTED
APPROVAL_REJECTED
MIGRATION_ITEM_PROCESSED
IDENTITY_RECOMMENDATION_CREATED
DRAFT_CREATED
54. AgentDecision
Optional but recommended entity:
AgentDecision
Represents one structured AI reasoning result without exposing hidden chain-of-thought.
Suggested fields:
id
user_id
decision_type
message_id
conversation_id
model_provider
model_name
model_version
prompt_version
structured_result
confidence
reason_summary
created_at
structured_result may be JSON because AI output schemas can evolve.
This is an appropriate use of JSON.
55. ClassificationEvaluation
Entity:
ClassificationEvaluation
Supports model regression testing.
Suggested fields:
id
message_id
expected_classification
expected_attention
expected_priority
source
created_at
Sources may include:
USER_CORRECTION
CURATED
RULE_CONFIRMED
56. ModelEvaluationRun
Optional entity:
ModelEvaluationRun
Suggested fields:
id
model_name
model_version
prompt_version
started_at
completed_at
sample_count
classification_accuracy
attention_accuracy
priority_accuracy
notes
57. AutomationPolicy
Entity:
AutomationPolicy
Stores user-level action autonomy settings.
Suggested fields:
id
user_id
action_type
autonomy_level
risk_ceiling
created_at
updated_at
Possible autonomy levels:
DISABLED
SUGGEST
APPROVAL_REQUIRED
AUTOMATIC
58. AutomationPause
Entity or state:
AutomationPause
Suggested fields:
id
user_id
mail_account_id_optional
reason
started_at
ends_at
created_by
Null mailbox means global pause.
59. NotificationPreference
Entity:
NotificationPreference
Suggested fields:
id
user_id
notification_type
minimum_priority
mail_account_id_optional
enabled
channel
created_at
updated_at
60. DailyBrief
Optional persisted entity:
DailyBrief
Useful if generated summaries need history.
Suggested fields:
id
user_id
brief_date
generated_at
needs_action_count
respond_count
waiting_count
system_alert_count
processed_count
summary_reference
61. Historical Provenance
Historical provenance should not rely exclusively on the current MailAccount.
Entity:
MessageProvenance
Suggested fields:
id
message_id
source_provider
source_mailbox_address
source_folder_path
source_provider_message_id
original_recipient
migration_run_id
recorded_at
This record should survive source-account retirement.
62. ExternalIdentity
Optional future entity:
ExternalIdentity
Represents known addresses associated with a person/contact.
This becomes useful when contact consolidation begins.
Suggested fields:
id
person_id
email_address
identity_type
source_system
source_record_id
is_preferred
63. Future Person Entity
The future contact consolidation module should introduce:
Person
rather than treating provider contact cards as canonical people.
Suggested fields:
id
user_id
display_name
given_name
family_name
organization
preferred_email
preferred_phone
created_at
updated_at
This should become the canonical person record.
64. Future ContactSource
Entity:
ContactSource
Represents one provider-native contact record.
Suggested fields:
id
person_id
provider_type
provider_account_id
provider_contact_id
source_record_version
last_synced_at
Potential providers:
ICLOUD
GOOGLE
MICROSOFT
OTHER
65. Future ContactField
Entity:
ContactField
Allows field-level provenance.
Suggested fields:
id
person_id
field_type
field_value
label
source_contact_id
is_preferred
confidence
This supports contact merging without losing where values came from.
66. Contact MergeCandidate
Future entity:
ContactMergeCandidate
Suggested fields:
id
person_a_id
person_b_id
match_score
match_signals
status
created_at
reviewed_at
67. Calendar Context Boundary
The data model should avoid owning full calendar functionality initially.
Future contextual entities may include:
CalendarEventReference
with fields such as:
provider
calendar_id
event_id
start_at
end_at
title
related_conversation_id
This should remain contextual rather than becoming a full calendar model while Fantastical remains the preferred calendar interface.
68. User Settings
Entity:
UserSetting
Do not store every application setting in one opaque JSON document if settings have operational significance.
Important settings should have explicit schema or domain-specific tables.
JSON may be used for low-risk presentation preferences.
69. Enumerations
Primary domain enums should be implemented consistently across services.
Examples:
ProviderType
MailboxType
OperatingMode
AttentionState
Priority
RetentionState
RuleStatus
RuleOrigin
AutonomyLevel
ApprovalStatus
MigrationStatus
DuplicateStatus
ActorType
Do not allow arbitrary free-text values for these domains.
70. JSON Usage Policy
JSON is acceptable for:
Provider-specific raw metadata
AI structured output
Diagnostic traces
Versioned capability payloads
Non-core extensible metadata
JSON should not replace normalized structures for:
Accounts
Messages
Recipients
Rules
Rule conditions
Rule actions
Approvals
Corrections
Projects
Migrations
Contacts
71. Soft Delete Policy
Entities that represent configuration should generally support retirement rather than destructive deletion.
Examples:
MailAccount
MailIdentity
Rule
Project
ProviderConnection
Possible fields:
is_active
retired_at
Audit records should never be cascade-deleted merely because a configuration entity is retired.
72. Message Deletion Semantics
The application's message record should distinguish:
Provider message deleted
Application metadata retained
Application metadata purged
Provider deletion must not automatically erase audit history.
73. Referential Integrity
Important relationships should use foreign-key constraints where practical.
Examples:
Message → MailAccount
Message → Conversation
MailIdentity → MailAccount
RuleVersion → Rule
RuleCondition → RuleVersion
RuleAction → RuleVersion
MigrationItem → MigrationRun
74. Provider IDs
Provider IDs should not be used as application primary keys.
Provider identifiers should have uniqueness constraints scoped appropriately.
Example:
UNIQUE (
mail_account_id,
provider_message_id
)
where provider guarantees make this safe.
75. Email Address Normalization
Email addresses should retain original display form where useful but also store normalized comparison values.
Normalization should not make unsafe assumptions about provider semantics.
At minimum:
Trim whitespace
Normalize domain casing
Preserve original address
Do not indiscriminately modify local-part semantics.
76. Subject Normalization
Normalized subjects may support conversation matching and duplicate detection.
Possible transformations:
Remove common Re:
Remove common Fwd:
Trim repeated whitespace
Normalize case for comparison
Original subject must always be preserved.
77. Duplicate Detection Indexes
Useful lookup fields include:
internet_message_id
normalized_subject
sender_address
received_at
content_hash
attachment_hash
Duplicate detection should not rely on one database uniqueness constraint.
78. Search-Oriented Indexing
Likely relational indexes:
message received_at
message sender_address
message internet_message_id
message mail_account_id
conversation attention_state
conversation priority
classification primary_classification
classification project_id
waiting expected_response_at
rule status
audit timestamp
migration status
Final indexing depends on actual workload.
79. Full-Text Search
Full-text search may later include:
Subject
Body cache
Sender
Summary
Attachment text
Provider-native search remains authoritative for content that is not locally stored.
80. Embedding Storage
If semantic search is added later, embeddings should be stored separately from the primary message record.
Potential entity:
SemanticEmbedding
Suggested fields:
id
entity_type
entity_id
embedding_model
embedding_version
vector
created_at
This allows re-embedding without rewriting core domain records.
81. Temporal History
Important state changes should be reconstructable through audit history.
Do not require every mutable table to become a temporal table if the audit model already preserves relevant transitions.
Use explicit versioning where operational behavior depends on exact past configuration, particularly:
Rules
AI classifier versions
Migration mappings
82. Correlation
The following should support correlation IDs:
ProcessingJob
MailCommand
RuleExecution
AuditEvent
MigrationRun
AgentDecision
This allows tracing one provider event through all downstream actions.
83. Idempotency
Entities representing commands and processing should support idempotency keys.
Examples:
MailCommand
MigrationItem
Provider notification processing
Repeated event delivery must not create duplicate actions.
84. Data Ownership
Primary ownership boundaries:
USER owns MailAccount
USER owns Rule
USER owns Project
USER owns LearnedPreference
MAIL ACCOUNT owns provider connection/folders/messages
MESSAGE belongs to CONVERSATION
RULE owns versions/conditions/actions
MIGRATION RUN owns migration items
85. Source-of-Truth Matrix
Recommended ownership of information:
Full mail body
Provider
Provider folder/label state
Provider
Application attention state
Inbox Agent
Application classification
Inbox Agent
Rule definitions
Inbox Agent
Audit
Inbox Agent
Historical migration provenance
Inbox Agent
OAuth credentials
Secure credential store
Contacts
Future canonical target TBD
Calendar
Existing calendar providers / Fantastical experience
86. Data Model Acceptance Criteria
The canonical model is acceptable when:
- Physical mailboxes and email identities are separate entities.
- Aliases can exist without fake mailboxes.
- Messages use application-owned canonical IDs.
- Provider message IDs are preserved independently.
- Recipients are normalized.
- Conversation state can exist independently of individual messages.
- Classification, attention, priority, and retention remain distinct.
- Rules are versioned and normalized.
- User corrections are stored explicitly.
- Learned preferences do not masquerade as deterministic rules.
- Approvals are distinct from command execution.
- Migration runs and message-level migration results are traceable.
- Historical provenance survives source-mailbox retirement.
- Audit events remain append-oriented.
- Provider synchronization state is first-class.
- The schema does not depend on Outlook.
- Future contacts can be modeled around canonical people and source records.
- Future iOS/web clients can use the same backend model.
- Calendar functionality does not need to be owned by the platform.
87. Canonical Modeling Principle
The system should preserve this distinction:
ACCOUNT
Where mail physically lives
IDENTITY
Which address represents the user
PERSON
Who someone actually is
MESSAGE
What was sent
CONVERSATION
What discussion it belongs to
CLASSIFICATION
What it means
ATTENTION
What needs to happen
RULE
What deterministic behavior applies
PREFERENCE
What the agent believes the user tends to prefer
APPROVAL
What the user authorized
COMMAND
What the application intends to change
AUDIT
What actually occurred
PROVENANCE
Where the data originally came from
These concepts should not be collapsed simply because a provider happens to model them differently.
