## TL;DR

Add an enrollment guard: before every enrollment, check whether the lead is already active in any sequence, and enroll only if the answer is no. Make enrollment idempotent with a per-lead lock so two runs racing each other cannot both enroll. Then audit current enrollments and exit the duplicate membership.

```text
agent enrolled the same lead in two sequences at once  -  they got the intro email from both tracks on the same morning
```

## Steps

1. Before enrolling, query the lead's active sequence memberships across all sequences, not just the target one. Expected: the lookup returns a membership list; empty means safe to enroll, non-empty means stop.

2. If the lead is already active somewhere, route to a join-or-exit decision instead of enrolling: either add them to the new track after exiting the old one, or skip. Expected: no lead ends up active in two sequences at the same time.

3. Put enrollments behind a single writer or a per-lead lock so two agent runs cannot enroll the same lead concurrently. Expected: a second concurrent enrollment attempt blocks or no-ops instead of creating a duplicate.

4. Audit existing enrollments for leads active in more than one sequence and exit the weaker membership. Expected: the audit returns zero double-active leads.

## Use this when

- a lead got the intro email from two tracks on the same morning
- two agent runs or two triggers can enroll the same lead
- CSV uploads and API enrollments share the same lead pool

## Not for this skill when

- a lead intentionally in two tracks (for example nurture plus a transactional track) - handle that with explicit exclusions, not this guard
- duplicate sends inside one sequence - that is a send-dedupe problem, not enrollment
- unsubscribe or suppression failures

## Variant phrasings

### lead got two intro emails the same day

Same root cause: no cross-sequence enrollment check before enrolling.

### agent double-enrolled a lead in two tracks

Same fix: global membership lookup plus idempotent enrollment.

### duplicate intro email from a different sequence

Same fix: the guard has to span sequences, not just check the target one.

## Why it happens

Enrollment checks are usually scoped to the target sequence: the agent asks 'is this lead in sequence A?' and never asks 'is this lead in any sequence?'. Two sequences, two agent runs, or a CSV upload plus an API enrollment race each other, and both checks pass because neither sees the other. There is no global enrollment state, so duplicates are the default outcome, not a freak accident.

## Edge cases

- Legit parallel tracks (nurture plus event reminders) - exclude defined track pairs from the guard explicitly rather than disabling it.
- Exiting a sequence mid-track can skip a breakup step the lead was owed - decide the exit behavior per track.
- Membership lookups can lag on some platforms - treat a stale empty result as untrusted and re-check before the first send.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_ec7m8anXDsPSIUvndS7X3Q
