Skip to content

fix(email): add EMAIL_DISABLE_AUTO_REPLY env var guard - #30790

Closed
phuongvm wants to merge 1 commit into
NousResearch:mainfrom
phuongvm:pr/email-auto-reply-guard
Closed

fix(email): add EMAIL_DISABLE_AUTO_REPLY env var guard#30790
phuongvm wants to merge 1 commit into
NousResearch:mainfrom
phuongvm:pr/email-auto-reply-guard

Conversation

@phuongvm

Copy link
Copy Markdown
Contributor

What does this PR do?

Add EMAIL_DISABLE_AUTO_REPLY environment variable to pause IMAP polling and block all SMTP send operations while still receiving and processing inbound emails. This prevents unsolicited auto-replies while keeping inbound email processing and cron triage functional.

Related Issue

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)

Changes Made

gateway/platforms/email.py (+37/-3 lines)

  1. IMAP polling guard (start_platform): Skip poll_loop creation when EMAIL_DISABLE_AUTO_REPLY=1/true/yes, with INFO log explaining the pause.
  2. SMTP send guards (3 methods):
    • _send_email(): Return disabled message ID, log WARNING with recipient and subject
    • _send_email_with_attachments(): Return disabled message ID, log WARNING
    • _send_email_with_file(): Return disabled message ID, log WARNING
  3. All three send methods return a synthetic message ID format <hermes-disabled-{uuid}@{domain}> so callers don't crash.
  4. Cron job triage (email_watch_hourly.py) is unaffected — inbound emails still processed.

How to Test

  1. Set EMAIL_DISABLE_AUTO_REPLY=1 in environment or .env
  2. Restart gateway: systemctl --user restart hermes-gateway
  3. Verify in logs: [Email] Platform PAUSED — IMAP polling disabled by EMAIL_DISABLE_AUTO_REPLY
  4. Send an email to the configured address — verify it's received and processed but no reply is sent
  5. Unset the variable and restart — verify normal operation resumes

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass
  • I've tested on my platform: Ubuntu 24.04 (WSL2)

Documentation & Housekeeping

  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A

Screenshots / Logs

[Email] Platform PAUSED — IMAP polling disabled by EMAIL_DISABLE_AUTO_REPLY. Cron job triage (email_watch_hourly.py) is unaffected.
[Email] AUTO-REPLY DISABLED — would have sent to user@example.com (subject: Test). Set EMAIL_DISABLE_AUTO_REPLY=0 to re-enable.

Add environment variable EMAIL_DISABLE_AUTO_REPLY to pause IMAP polling
and block all SMTP send operations (_send_email, _send_email_with_attachments,
_send_email_with_file) while still receiving and processing inbound emails.

When enabled (1/true/yes):
- IMAP poll_loop is skipped during start_platform() with INFO log
- All SMTP send methods return a disabled message ID and log a WARNING
- Cron job triage (email_watch_hourly.py) is unaffected

Use case: prevent unsolicited auto-replies while keeping inbound email
processing and triage functional.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/gateway Gateway runner, session dispatch, delivery platform/email Email (IMAP/SMTP) adapter labels May 23, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

Related: #5717 (EMAIL_SUPPRESS_OUTBOUND kill switch). Similar concept — #5717 blocks SMTP only, this PR also pauses IMAP polling. Consider consolidating.

@phuongvm

Copy link
Copy Markdown
Contributor Author

Good catch on the relation to #5717. The key difference is scope:

The use case here is preventing unsolicited auto-replies during debugging/testing windows — we want to stop all automated email activity (both sending and polling-triggered actions) while still receiving and triaging inbound mail.

Consolidation into a unified suppression mechanism makes sense as a follow-up, but I think this PR is valuable standalone since it addresses a different operational need. Happy to discuss merging approaches if maintainers prefer.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for addressing the operator need to prevent unintended email replies. The member discussion linking #5717 was useful context.

This automated hermes-sweeper review is closing the PR as a configuration-direction mismatch:

  • The proposed public mechanism, EMAIL_DISABLE_AUTO_REPLY, is a non-secret behavioral feature flag in .env. Repository policy requires behavioral settings and feature flags to live in config.yaml instead (AGENTS.md:102-107, AGENTS.md:620-623).
  • The submitted change targets gateway/platforms/email.py, which was removed when email moved into the bundled platform plugin in 560010547. Current SMTP paths are in plugins/platforms/email/adapter.py, including the adapter sends (:921-1165) and standalone delivery (:1190-1230).

A focused follow-up using a platforms.email config setting, integrated with the email plugin and every current SMTP egress path, would be the supported direction.


Closed as not-planned per standing maintainer policy (env-var-for-config). This is an automated hermes-sweeper review and a configuration-direction decision, not a judgment on the contribution’s quality.


Closed as not-planned per standing maintainer policy (env-var-for-config). This is a design-direction decision, not a code-quality judgment — see the Contribution Rubric in AGENTS.md for what the project is looking for. If you believe this policy was misapplied to your change, comment here and a maintainer will take a look.

@teknium1 teknium1 closed this Jul 13, 2026
@teknium1 teknium1 added the sweeper:not-planned Sweeper: closed per standing maintainer policy (design direction) label Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P3 Low — cosmetic, nice to have platform/email Email (IMAP/SMTP) adapter sweeper:not-planned Sweeper: closed per standing maintainer policy (design direction) type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants