# Agent emailed hired candidates because a custom Lever stage name was unmapped

## TL;DR
The agent filtered out hired candidates by matching stage names, but one custom Lever stage name was not in the map, so those hires looked like active candidates. Fix: fetch the stage list from the Lever API and match on stage IDs, and alert on any stage name the map does not recognize. Name-based matching breaks the moment someone renames a stage.

## Error
```text
agent emailed candidates who had already been hired  -  the 'hired' stage mapping missed one custom stage name in Lever
```

## Steps
1. Pull the full stage list from the Lever API for the affected requisitions and compare against your map.
   Expected: you find the unmapped custom stage name, e.g. "Offer Accepted - Start Date Set".
2. Switch the filter to stage IDs, not names: resolve each stage's ID from the API at sync time and classify by ID.
   Expected: renames stop breaking the filter.
3. Add an unknown-stage alert: any stage name or ID not in the map pages the team instead of defaulting to "active".
   Expected: the next new stage is caught on first sight, not after emails go out.
4. Re-run the filter over the current pipeline and list everyone currently classified as active whose stage is actually a hired-equivalent.
   Expected: the full list of misclassified candidates, excluded from outreach.
5. Backfill the map for all custom stages across all requisitions, not just the one that failed.
   Expected: no other custom hired-equivalent stage is lurking.

## Use this when
- outreach reaches hired or rejected candidates
- stages were renamed or customized in Lever
- the agent filters by stage name
- new requisitions add new stage names

## Not for this skill when
- the stage was right but the sync was stale (that is the webhook/caching problem)
- the candidate was hired at a different company and you emailed anyway (that is suppression-list scope)
- the mapping is by ID already and still missed (check whether the requisition was archived and re-created with new IDs)

## Variant phrasings
- "Lever custom stage not in mapping"
- "hired candidates got outreach emails"
- "stage name mismatch Lever"
- "unknown stage defaulted to active"

## Why it happens
Lever lets teams rename and add stages freely, and a hardcoded name map is a snapshot that decays. The miss was silent because the code treated "not in map" as "still active" instead of "unknown". Defaulting unknown to the permissive bucket turns every future stage rename into an outreach bug.

## Edge cases
- Archived requisitions can carry their own stage sets; map per requisition, not globally.
- Stage IDs can change if a requisition is cloned; re-resolve on sync, do not cache forever.
- Some teams use hired-equivalents like "Alumni" or "Internal Transfer"; classify by meaning with the hiring team, not by guessing.
- Keep the unknown-stage alert noisy at first; tune it down only after the map stabilizes.

## Provenance

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