[object Object]

← back to Rentv

pr/replies: Cody gate — guard the broadened opt-out regex against IRREVERSIBLE false positives. (1) negation lookbehind so 'don''t/do not/never stop sending' is NOT an opt-out (was permanently suppressing engaged leads); (2) redirect lookahead so 'stop sending TO my old address / IT to X' (lead giving a new address) isn't suppressed; (3) dropped bare 'no longer interested' — a soft-no/timing reply ('no longer interested in a Q3 close'), NOT a legal opt-out, was over-suppressing CRE leads. Verified 18 opt-outs caught, 0 false positives on 13 negation/non-opt-out cases

8aac792283ec2af16ad0c204c5c38652342d4f2e · 2026-08-05 22:00:30 -0700 · Steve

Files touched

Diff

commit 8aac792283ec2af16ad0c204c5c38652342d4f2e
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Aug 5 22:00:30 2026 -0700

    pr/replies: Cody gate — guard the broadened opt-out regex against IRREVERSIBLE false positives. (1) negation lookbehind so 'don''t/do not/never stop sending' is NOT an opt-out (was permanently suppressing engaged leads); (2) redirect lookahead so 'stop sending TO my old address / IT to X' (lead giving a new address) isn't suppressed; (3) dropped bare 'no longer interested' — a soft-no/timing reply ('no longer interested in a Q3 close'), NOT a legal opt-out, was over-suppressing CRE leads. Verified 18 opt-outs caught, 0 false positives on 13 negation/non-opt-out cases
---
 src/pr/services/replies.js | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/pr/services/replies.js b/src/pr/services/replies.js
index f870f388..fa047794 100644
--- a/src/pr/services/replies.js
+++ b/src/pr/services/replies.js
@@ -9,13 +9,17 @@ const outreach = require('./outreach');
 const people = require('./people');
 const { normalizeEmail } = require('../lib/normalize');
 
-// Opt-out language in an inbound reply → permanent suppression (CAN-SPAM). Tested against a broad
-// phrasing set: catches "don't/do not email me", "take me off (your list)", "remove me/my email/name",
-// "stop contacting/emailing/sending", "opt out", "unsubscribe", "no longer wish/want", "cease contact".
-// Bias toward catching opt-outs (a missed one is a compliance violation; an over-catch only loses a
-// lead) — but tuned to avoid clear false positives ("remove the typo", "stop by", "I don't think…").
+// Opt-out language in an inbound reply → PERMANENT, IRREVERSIBLE suppression (CAN-SPAM). Because it
+// can't be undone, false positives (suppressing an engaged lead) matter as much as false negatives.
+// Catches: unsubscribe, opt out, take me off, remove me/my email/name/from list, don't/do not
+// contact/email, stop contacting/emailing/sending, no longer wish/want to hear/receive, cease contact.
+// GUARDS against the dangerous false positives (Cody gate):
+//   • "(don't|do not|never) stop …" — negation lookbehind, so "don't stop sending me these" is NOT an opt-out
+//   • "stop sending TO my old address / IT to …" — redirect lookahead, they want contact elsewhere, not to stop
+//   • bare "no longer interested" is a soft-no / lead-status, NOT a legal opt-out — dropped (was over-suppressing
+//     CRE timing/scope replies like "no longer interested in a Q3 close"); requires "no longer wish/want to hear/receive".
 // `blob` is already lowercased by the caller. Curly + straight apostrophes both handled.
-const OPT_OUT_RE = /\bunsubscribe\b|\bopt[\s-]?out\b|\btake me off\b|\bremove (me|my (name|e-?mail|address)|from (your|the|this|our))\b|\b(do ?n['’]?t|do not) (contact|e-?mail|message|reach)\b|\bstop (contact|e-?mail|messag|send|reach)\w*\b|\bno longer (wish|want|interested)\b|\bcease (all )?(contact|communicat|e-?mail)\w*\b/;
+const OPT_OUT_RE = /\bunsubscribe\b|\bopt[\s-]?out\b|\btake me off\b|\bremove (me|my (name|e-?mail|address)|from (your|the|this|our))\b|\b(do ?n['’]?t|do not) (contact|e-?mail|message|reach)\b|(?<!n['’]?t\s)(?<!\bnot\s)(?<!\bnever\s)\bstop (contact|e-?mail|messag|send|reach)\w*\b(?!\s+(to|it)\b)|\bno longer (wish|want)\w* to (hear|receive|be contacted|be emailed|get)\b|\bcease (all )?(contact|communicat|e-?mail)\w*\b/;
 
 /**
  * Sync provider threads for all sent messages that have a provider_thread_id.

← dbb25bf7 pr/replies: broaden opt-out detection (CAN-SPAM). The old re  ·  back to Rentv  ·  auto-save: 2026-08-05T22:16:18 (7 files) — data/deals-regist 61c09db7 →