Creates openspec/changes/email-loop-prevention/ with all artifacts: - proposal.md: Why (MAILER-DAEMON bounce loop incident), what changes (automated sender detection + message-count cap), capabilities affected - design.md: Two-layer defence rationale, detection signal table, decisions on channel/agent boundary split, 20-message cap, one-shot alert, CC-only routing; risks and trade-offs documented - specs/email-channel/spec.md: ADDED requirements for detect_automated_message(), is_automated/automated_reason message dict fields, no-reply guarantee - specs/registration-notifications/spec.md: ADDED requirements for notify_loop_escalation() — alert content, one-shot guarantee, CC-only routing, dev-mode guard - tasks.md: All 6 sections fully checked (implementation already complete) https://claude.ai/code/session_01KwvR5hDPjSuJg4kvw5b5e5
55 lines
2.8 KiB
Markdown
55 lines
2.8 KiB
Markdown
## ADDED Requirements
|
|
|
|
### Requirement: Automated sender detection
|
|
The system SHALL detect whether an inbound email was sent by an automated system rather than a human, before the message is processed by the agent.
|
|
|
|
#### Scenario: MAILER-DAEMON sender
|
|
- **WHEN** an email arrives with a sender local-part of `mailer-daemon`, `postmaster`, `noreply`, `no-reply`, `donotreply`, or `bounce` (case-insensitive)
|
|
- **THEN** the system SHALL flag the message as automated with a reason string identifying the sender pattern
|
|
|
|
#### Scenario: RFC 3834 Auto-Submitted header
|
|
- **WHEN** an email contains an `Auto-Submitted` header with any value other than `no`
|
|
- **THEN** the system SHALL flag the message as automated, citing the header value in the reason
|
|
|
|
#### Scenario: Auto-Submitted: no is not automated
|
|
- **WHEN** an email contains `Auto-Submitted: no`
|
|
- **THEN** the system SHALL NOT flag the message as automated based on this header
|
|
|
|
#### Scenario: Microsoft Exchange auto-reply suppression
|
|
- **WHEN** an email contains an `X-Auto-Response-Suppress` header (any value)
|
|
- **THEN** the system SHALL flag the message as automated
|
|
|
|
#### Scenario: Delivery Status Notification (RFC 3462)
|
|
- **WHEN** an email has `Content-Type: multipart/report`
|
|
- **THEN** the system SHALL flag the message as automated, as this indicates a machine-generated delivery status or read receipt
|
|
|
|
#### Scenario: X-Loop header
|
|
- **WHEN** an email contains an `X-Loop` header (any value)
|
|
- **THEN** the system SHALL flag the message as automated
|
|
|
|
#### Scenario: Bulk or junk precedence
|
|
- **WHEN** an email has a `Precedence` header with value `bulk` or `junk`
|
|
- **THEN** the system SHALL flag the message as automated
|
|
|
|
#### Scenario: Bounce / OOO subject line
|
|
- **WHEN** an email subject matches patterns indicating delivery failure or automated response (e.g. "Undelivered Mail", "Mail Delivery Failed", "Out of Office", "Abwesenheitsnotiz", "Automatische Antwort")
|
|
- **THEN** the system SHALL flag the message as automated
|
|
|
|
#### Scenario: Normal parent message
|
|
- **WHEN** an email has a normal human sender address and no automated-sender headers
|
|
- **THEN** the system SHALL NOT flag the message as automated
|
|
|
|
### Requirement: Automated messages are never replied to
|
|
The system SHALL NOT send any reply to a message flagged as automated.
|
|
|
|
#### Scenario: Bounce message arrives
|
|
- **WHEN** the system receives a message flagged as automated
|
|
- **THEN** the system SHALL mark the message as read (IMAP Seen flag)
|
|
- **AND** the system SHALL call the agent's automated-message handler
|
|
- **AND** the system SHALL NOT send any outbound email reply
|
|
|
|
### Requirement: Message dict includes automation flag
|
|
Every message returned by `fetch_unread_messages()` SHALL include:
|
|
- `is_automated` (boolean): whether the message was flagged as automated
|
|
- `automated_reason` (string): human-readable reason if flagged, empty string otherwise
|