generated from coulomb/repo-seed
feat: start mailbox evidence scanner
This commit is contained in:
98
docs/initial-runtime-architecture.md
Normal file
98
docs/initial-runtime-architecture.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 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/
|
||||
```
|
||||
Reference in New Issue
Block a user