- email_channel.py: add detect_automated_message() that inspects RFC 3834
Auto-Submitted, mailer-daemon/postmaster sender patterns, X-Loop,
multipart/report Content-Type, Precedence, and subject heuristics.
fetch_unread_messages() now includes is_automated / automated_reason
in every message dict.
- main.py: if is_automated is set, call agent.handle_automated_message()
instead of process_message() — no reply is ever sent to a bounce source.
- agent/core.py: add MAX_USER_MESSAGES = 20 cap; process_message() returns
"" without replying once a conversation exceeds the limit and calls
notifier.notify_loop_escalation() on first breach. New public method
handle_automated_message() records the event and triggers the same
one-shot admin alert.
- models/conversation.py: add loop_escalated: bool field (persisted) so
the admin alert fires at most once per conversation.
- notifications/notifier.py: add notify_loop_escalation() which sends a
plain-text warning to the admin CC list (Markus Graf / spielgruppen@).
https://claude.ai/code/session_01KwvR5hDPjSuJg4kvw5b5e5