# Stage 8 — Offer Agent (code)

The closer. Once a human approves the offer terms, this agent delivers the offer with an
e-signature link, reminds as the deadline approaches, answers routine FAQs instantly, and tracks
the response — congratulating an accept and gracefully handling a decline.

## The two hard gates
- **GATE 1 — No human-approved terms, no offer.** If `offer_approved` isn't TRUE with a named
  approver, the agent escalates instead of sending. It never composes or sends terms on its own.
- **GATE 2 — The agent never negotiates.** Any candidate question touching salary, equity, title,
  bonus, or terms is routed to the recruiter immediately, unanswered. The FAQ set covers routine
  logistics only (start date, benefits packet, remote policy, equipment).

## Files
- `stage8_offer_agent.py` — the agent.
- `stage8_candidates_sample.csv` — offer-stage candidates (your ATS exports this).
- `stage8_offers_sample.json` — validity window, reminder timing, the routine FAQ set, recruiters.
- `stage8_offer_README.md` — this file.

## What it does, by state
- **`to_send`, approved** → delivers offer + e-sign link with a clear validity window.
- **`to_send`, NOT approved** → blocked; escalates for approval (Gate 1).
- **`sent`, no response** → friendly reminder after 2 days; urgent-but-warm note + recruiter flag when expiring.
- **`sent`, routine question** → instant FAQ answer.
- **`sent`, terms question** → straight to the recruiter, unanswered (Gate 2).
- **`accepted`** → congratulations + advance to Hired; recruiter notified.
- **`declined`** → warm thank-you + a one-question feedback ask; recruiter closes out (human).

## Safety rails (built in)
- Dry-run by default; texts only with consent; audit log of every send, answer, escalation, and advance.

## Run it
`python stage8_offer_agent.py` — all seven paths play out, nothing is sent.

## Going live
1. Edit templates, validity window, reminder timing, and the FAQ set in CONFIG / the JSON.
2. Wire the PROVIDER HOOKS: `generate_esign_link` (DocuSign / Dropbox Sign / PandaDoc),
   `send_email` / `send_sms`, `notify_person`, `advance_stage` (ATS update).
3. Replace the `valid_until` placeholder with a real date computed from the send timestamp.
4. `DRY_RUN = False`, test on your own addresses.

## Notes
- `days_since_sent` and `candidate_question` simulate time and inbound questions so every path
  shows in one run. In production, responses and questions come from your e-sign tool's webhooks
  and your inbox integration, and the agent runs on a schedule. Track sent reminders to avoid repeats.
- The keyword escalation list errs on the side of routing to a human — tune it, but keep it generous.
