generated from coulomb/repo-seed
99 lines
3.2 KiB
Markdown
99 lines
3.2 KiB
Markdown
# Initial Runtime Architecture
|
|
|
|
## Status
|
|
|
|
This is the first implementation architecture for the mailbox evidence scanner
|
|
slice. It is intentionally small and stdlib-only so the repo can run before a
|
|
larger service stack is chosen.
|
|
|
|
## Service Boundary
|
|
|
|
The first slice is a CLI scanner:
|
|
|
|
```text
|
|
email-connect scan-mailbox --config config/mailbox.example.yml --out reports/
|
|
```
|
|
|
|
It scans an inbound return mailbox source, classifies messages, stores scan
|
|
state in SQLite, and writes timestamped CSV evidence reports.
|
|
|
|
The initial source implementation supports fixture directories. The IMAP
|
|
connector remains the next mailbox boundary to complete under
|
|
`EMAIL-WP-0002-T02`.
|
|
|
|
## Package Layout
|
|
|
|
```text
|
|
src/email_connect/
|
|
adapter_contract.py # coordination-engine descriptor and evidence ceiling
|
|
cli.py # command line entry points
|
|
config.py # config loading
|
|
evidence.py # native class to normalized evidence mapping
|
|
models.py # mailbox, parse, evidence, endpoint quality dataclasses
|
|
parser.py # MIME/header parsing and conservative classification
|
|
reporting.py # CSV report generation
|
|
scanner.py # scan orchestration
|
|
storage.py # SQLite state store
|
|
```
|
|
|
|
## Persistence
|
|
|
|
SQLite is the MVP store. The initial schema includes:
|
|
|
|
- `mailbox_scans`
|
|
- `mailbox_messages`
|
|
- `parsed_messages`
|
|
- `evidence_candidates`
|
|
|
|
Message deduplication is keyed by mailbox ID, IMAP UID when present, message ID,
|
|
received timestamp, sender, subject hash, and body hash. Evidence
|
|
deduplication follows the workplan fields: message, parser version, normalized
|
|
event, affected recipient, original message, SMTP/enhanced status, and reason.
|
|
|
|
## Evidence Mapping
|
|
|
|
Parser output is represented as `ParsedMailboxMessage`. The mapper converts it
|
|
to `EmailEvidenceCandidate` using coordination-engine event names and advisory
|
|
assessment classes.
|
|
|
|
Examples:
|
|
|
|
- `hard_bounce` -> `notification.endpoint.rejected_permanent`
|
|
- `soft_bounce` -> `notification.endpoint.rejected_temporary`
|
|
- `out_of_office` -> `interaction.out_of_office_received`
|
|
- `human_reply` -> `interaction.reply_received`
|
|
|
|
The mapper does not emit evidence for unrelated messages. Unknown return
|
|
messages stay visible as `notification.endpoint.unknown`.
|
|
|
|
## coordination-engine Alignment
|
|
|
|
The implementation keeps these coordination-engine concepts explicit:
|
|
|
|
- adapter descriptor
|
|
- adapter capability profile
|
|
- evidence ceiling
|
|
- advisory assessment
|
|
- endpoint quality update shape
|
|
- event observation and raw reference preservation
|
|
- golden tests for overclaim prevention
|
|
|
|
Email evidence remains below the coordination result layer. The scanner does
|
|
not infer inbox placement, human awareness, legal acceptance, payload access, or
|
|
case success.
|
|
|
|
## Provider Boundary
|
|
|
|
Provider webhook ingestion and outbound send APIs are deliberately outside this
|
|
slice. The mailbox scanner uses the same evidence model so future provider
|
|
events can enter through a parallel ingestion path and converge at the same
|
|
normalization layer.
|
|
|
|
## Development Commands
|
|
|
|
```bash
|
|
PYTHONPATH=src python3 -m unittest discover -s tests
|
|
PYTHONPATH=src python3 -m email_connect.cli adapter-descriptor
|
|
PYTHONPATH=src python3 -m email_connect.cli scan-mailbox --config config/mailbox.example.yml --out reports/
|
|
```
|