From 2e16638c290fa9d55c012596aae2d86c9fe0ee6d Mon Sep 17 00:00:00 2001 From: tps-anvil Date: Sun, 17 May 2026 16:04:08 +0000 Subject: [PATCH] fix(mail): guard sendMessage against leaking into production maildir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent tests from accidentally writing to the default ~/.tps/mail/ directory when TPS_MAIL_DIR is not explicitly set. The guard activates when NODE_ENV=test or TPS_MAIL_REQUIRE_EXPLICIT_DIR is set. Root cause: mail.test.ts calls sendMessage() with beforeEach setting TPS_MAIL_DIR to a temp directory, but if the module is loaded outside the test framework (e.g. direct import), messages land in the real maildir — as seen with 188 phantom msg-NN messages in a production inbox. --- packages/cli/src/utils/mail.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/cli/src/utils/mail.ts b/packages/cli/src/utils/mail.ts index d9fd2c3..20cef7d 100644 --- a/packages/cli/src/utils/mail.ts +++ b/packages/cli/src/utils/mail.ts @@ -164,6 +164,18 @@ export function sendMessage(to: string, body: string, from?: string): MailMessag assertValidAgentId(sender); assertValidBody(body); + // Guard: when running in test mode or when the caller has explicitly + // opted in, refuse to write to the default ~/.tps/mail/ directory + // unless TPS_MAIL_DIR is set. This prevents tests from accidentally + // spraying messages into the real production maildir (e.g. when + // imported directly without beforeEach setting TPS_MAIL_DIR to a temp dir). + if ((process.env.NODE_ENV === "test" || process.env.TPS_MAIL_REQUIRE_EXPLICIT_DIR) && !process.env.TPS_MAIL_DIR) { + throw new Error( + "TPS_MAIL_DIR must be set explicitly in test mode. " + + "Refusing to write to the default production maildir.", + ); + } + const inbox = getInbox(to); const quotaCount = countInboxMessages(to); if (quotaCount >= MAX_INBOX_MESSAGES) {