The rule
Before drafting outbound to any prospect, run a prior-decision check. Specifically:
1. Search Gmail (sender, recipient email, prospect name): from:rachel@skyrun.com (prospect_name OR prospect_email) "no" OR "not a fit" OR "decline" OR "skip" OR "pass"
2. Search active-deal memory files at ~/.claude/projects/-Users-josephbowens-Desktop-SkyRun/memory/project_active_deal_*.md for the prospect name + email. Read frontmatter for CLOSED-LOST, Rachel-vetoed, DO NOT OUTREACH.
3. Check the knowledge graph for any deal entity tagged closed_lost, vetoed, do_not_contact.
4. Check the DNC ledger (~/Desktop/SkyRun/DNC_active_homeowners.json) — current homeowners are also off-limits per the DNC rule.
If ANY of those return a hit, DO NOT draft. Surface the hit to the queue with status vetoed_blocked and an explicit reason. Joseph re-decides from there if needed.
Verbatim trigger incident
2026-04-27 21:38 UTC — Daniela@skyrun.com routed Tim Beegle's STR-property-mgmt inquiry to Rachel + Joseph (gmail thread 19dd0e03b7d8b47b).
Rachel's response 1 minute later:
> "Regarding Tim Beegle. This is a no"
(gmail msg 19dd0e1aa27cf9f8)
Joseph: "Got it."
2026-04-30 14:57 UTC — Brooke@skyrun.com (Winter Park guest support) forwarded a duplicate Tim Beegle inquiry to Joseph (gmail thread 19ddee53baaaf251). Brooke didn't know about Rachel's Apr 27 veto.
2026-04-30 16:07 UTC — An agent drafted a 30%-pitch intro reply (gmail draft 19ddf254dde9928e) and queued it as an active-deal RED entry in project_active_deal_tim_beegle.md, NOT acknowledging Rachel's 4/27 veto.
2026-05-02 03:30 UTC — Joseph caught the regression and discarded the draft. Memory file converted to CLOSED-LOST. This rule added.
The structural pattern
This is the same shape as the Hadank false-positive (feedback_hs_stage_source_of_truth.md):
| Hadank | Tim Beegle |
|---|---|
| Agent treated 4/30 contract-sent email as fresh state | Agent treated 4/30 Brooke-forward as fresh inbound |
| Without checking live HS dealstage | Without checking prior Rachel-veto thread |
| Created stale stage drift | Created phantom active-deal state |
Mechanical check (for skill prompts)
Before composing ANY draft for a previously-unseen-to-this-session prospect, run this query block:
python
Pseudo-code; agent should perform via Gmail MCP + memory file reads
prospect_name = "Tim Beegle"
prospect_email = "timbeegle@yahoo.com"
1. Gmail search for Rachel-veto on this prospect
veto_hit = gmail_search(f'from:rachel@skyrun.com ({prospect_name} OR {prospect_email}) "no" OR "not a fit" OR "decline"')
2. Memory file scan
mem_hit = grep_memory(f'CLOSED-LOST.{prospect_name}|Rachel-vetoed.{prospect_name}|DO NOT OUTREACH.*{prospect_name}')
3. KG check
kg_hit = kg_query(f"deals.tags contains 'vetoed' or 'closed_lost' for prospect={prospect_name}")
4. DNC check (already required by current_owner_check)
dnc_hit = dnc_check.is_current_homeowner(email=prospect_email, name=prospect_name)
if any([veto_hit, mem_hit, kg_hit, dnc_hit]):
queue_blocked(reason=...) # surface to Joseph; do NOT draft
return
Wired into
live-ea/SKILL.md— Step 4 pre-draft check (to be added in next skill update if not already)qb-quarterback/SKILL.md— samestalled-deal-watchdog/SKILL.md— already haslifecyclestage=closedlostskip; this rule extends to memory-file-CLOSED-LOST tagsfeedback_freshness_before_surface.md— sister rule for stage-not-stalefeedback_hs_stage_source_of_truth.md— sister rule for current-stage-from-live-API
Cross-references
project_active_deal_tim_beegle.md— the live test case (CLOSED-LOST, Rachel-vetoed)project_active_deal_hadank.md— the parallel Hadank case (stage-drift class, same root cause)feedback_no_fabrication_personal.md— overarching no-fabrication discipline