[object Object]

← back to Dw Signup Fulfillment

TK-10830: one-shot guard on Kelly reply (prevent duplicate sends)

49e1750ab659d4c62e3a24fe7e5ba050d31d59c4 · 2026-09-02 11:49:37 -0700 · Steve Abrams

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzrHtgk5Qq7kpdfaWeDk97

Files touched

Diff

commit 49e1750ab659d4c62e3a24fe7e5ba050d31d59c4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed Sep 2 11:49:37 2026 -0700

    TK-10830: one-shot guard on Kelly reply (prevent duplicate sends)
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
    Claude-Session: https://claude.ai/code/session_01WzrHtgk5Qq7kpdfaWeDk97
---
 .gitignore          |  1 +
 send-kelly-reply.js | 11 +++++++++++
 2 files changed, 12 insertions(+)

diff --git a/.gitignore b/.gitignore
index be78ded..f16e31a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ data/minted-cards-honor-worklist.jsonl
 data/honor-reissue-ledger*.jsonl
 data/*.bak-*
 data/latest.json
+.kelly-reply-tk10830.sent
diff --git a/send-kelly-reply.js b/send-kelly-reply.js
index 8f1ca04..57c53a9 100644
--- a/send-kelly-reply.js
+++ b/send-kelly-reply.js
@@ -7,6 +7,16 @@
 // DRY_RUN defaults ON; pass DRY_RUN=0 to actually send. Creds resolve from secrets-manager/.env
 // (GEORGE_AUTH) + george-gmail/.env (GEORGE_EXTERNAL_SEND_TOKEN) via lib/config.js.
 const email = require('./lib/email');
+const fs = require('fs');
+const path = require('path');
+
+// One-shot guard: this reply already SENT (twice) on 2026-09-02. Refuse further sends
+// so an accidental re-run can't spam Kelly. Delete the sentinel below to deliberately resend.
+const SENT_FLAG = path.join(__dirname, '.kelly-reply-tk10830.sent');
+if (fs.existsSync(SENT_FLAG) && process.env.FORCE_RESEND !== '1') {
+  console.error('ABORT: Kelly reply already sent (sentinel .kelly-reply-tk10830.sent). Set FORCE_RESEND=1 to override.');
+  process.exit(1);
+}
 
 const to = 'kyounge@umich.edu';
 const subject = 'Re: Your Designer Wallcoverings samples — your 3 free swatches';
@@ -23,5 +33,6 @@ const html = [
   const r = await email.sendEmail({ to, subject, html, source: 'kelly-reply-tk10830' });
   console.log('send result:', JSON.stringify(r));
   if (r && r.ok === false) { console.error('SEND FAILED — not sent.'); process.exit(1); }
+  if (r && !r.dryRun) { try { fs.writeFileSync(SENT_FLAG, new Date().toISOString() + '\n'); } catch (_) {} }
   console.log(r && r.dryRun ? 'DRY_RUN — nothing sent (re-run with DRY_RUN=0 to send).' : 'SENT to ' + to);
 })().catch(e => { console.error('error:', e.message); process.exit(1); });

← 487679a TK-11114: R4 proof — DW signup verify-email fixed + verified  ·  back to Dw Signup Fulfillment  ·  TK-11114: dry-run-safe verify-email backfill executor (doubl cb069ce →