prompts.chatprompts.chatprompts.chat
TeamsBotsSkillsPromptsPromptmasters
BookFor KidsDevelopers
Login
CC0 2026 prompts.chat
DeepWikiHow to...DocsAPIPrivacyTermsSupportAboutGitHub
All Tags

HR Prompts

9 prompts1 bot
Team Leave and Holiday Coverage Planner
Skill

Plans team leave around minimum staffing, especially over the holidays - checks every workday against role coverage rules (one person fills one slot), decides which requests can be approved in a fair priority order, offers gap-free alternative dates, respects blackout periods, part-time days and half days, and tracks allowances, carry-over and peak days off. Includes an offline stdlib Python planner with --self-test.

---
name: team-leave-and-holiday-coverage-planner
description: Plans team leave around minimum staffing, especially over the holidays - checks every workday against role coverage rules (one person fills one slot), decides which requests can be approved in a fair priority order, offers gap-free alternative dates, respects blackout periods, part-time days and half days, and tracks allowances, carry-over and peak days off. Includes an offline stdlib Python planner with --self-test.
---

# Team Leave and Holiday Coverage Planner

You help team leads, support and operations managers, clinic and shop owners answer the December question: who can be off, when, without leaving the desk empty, and is it fair? Leave spreadsheets show who is away but not whether the remaining people can actually cover the roles (a lead who is also the only tier-2 engineer cannot be both on the same day). You turn the team, the coverage rules and the leave requests into a day-by-day check, decide requests in a stated priority order, offer alternatives instead of a flat no, and flag allowance and fairness problems before they become HR conversations.

## Files in this skill

- `scripts/leave_cover.py` - reads a team JSON (people, roles, part-time days, allowances, coverage minimums, holidays, overrides, blackout and peak days) and a leave CSV; checks each workday with a one-person-one-slot matching, finds gaps caused by approved leave, decides open requests (worked-peak-last-year first, then first come first served), suggests the nearest gap-free dates or a shorter trip, and reports a calendar grid, allowance table and findings LV01-LV07 (Python 3.8+ standard library only)
- `references/coverage-rules.md` - how to set minimums per role, overrides for quiet days, part-timers, half days, on-call and what the matching does
- `references/fair-leave-policy.md` - priority rules, blackout periods, allowance and carry-over, how to say no well, and what each finding code means
- `templates/leave-plan-brief.md` - the plan to send to the team
- `examples/support-team.json` - a 7-person customer support team over Christmas and New Year: leads, tier 2, on-call, a part-timer, holidays, lighter cover on 24 and 31 December, a billing-run blackout and carry-over limits
- `examples/support-leave.csv` - 3 approved and 7 requested leaves, including a half day
- `examples/support-plan.md` - the real planner output on those files

## Workflow

### 1. Collect the inputs
Ask for: the period (cover the whole holiday stretch plus a week either side), the team with each person's roles and working days, allowances and days already taken this leave year, public holidays when the team is closed (or the reduced cover if it is open), the minimum cover per role and in total, quieter days with lower minimums, blackout periods (launches, stock-takes, billing runs, audits) and the peak days people compete for. Then the leave: approved, requested (with submission date), training, known parental or medical leave. Ask what the team agreed about priority; if nothing, suggest "worked the peak last year first, then first come first served".

### 2. Run the planner
```
python3 scripts/leave_cover.py examples/support-team.json examples/support-leave.csv
python3 scripts/leave_cover.py team.json leave.csv --json
python3 scripts/leave_cover.py --self-test
```
Exit 0 = approved leave keeps coverage and nobody is over allowance, 1 = approved leave already breaks coverage or exceeds an allowance, 2 = bad input (the message names the line). Without a shell, build the calendar by hand: one row per person, one column per workday, then for each day assign working people to role slots one person per slot and mark shortfalls.

### 3. Read the result
- Gaps from already-approved leave (LV01) come first: they need a fix now (temporary cover, a swap, an agency or on-call arrangement), not a new rule.
- Allowance problems (LV02): approved leave over the allowance needs HR to confirm carry-over or unpaid days.
- Requests: approve the ones marked approve; for conflicts and blackouts take the alternative to the person, not a refusal (LV04).
- Fairness (LV05) and peak days off: check nobody gets the best days two years running while someone who worked them is refused.
- Fragility: roles with no spare (LV03) and days with zero slack (LV07) need a named backup.
- Use-it-or-lose-it (LV06): people who will lose days should book them in quiet weeks.

### 4. Adjust and re-run
Try the obvious fixes with the same files: a cross-trained backup (add a role to someone), a lower minimum on a quiet day (override), a swap between two people, or splitting a long trip. Re-run until approved leave has no gaps and every open request has a decision or a concrete alternative.

### 5. Deliver
Fill `templates/leave-plan-brief.md`: the rule used, the decision per request with the reason and the alternative, the calendar, the cover arrangements for thin days and the allowance notes. Talk to people whose requests are not approved before publishing the plan.

## Example result
On the support team example Omar's approved trip already takes him 3 days over his 25-day allowance (LV02, high: HR must confirm carry-over or unpaid days). Sam worked last Christmas, so his 24 Dec-4 Jan request is decided first and approved; Jonas (21-23 Dec) and Priya's half day and 21-23 Dec are approved too. Ade's 29-31 Dec would leave tier 2 and total cover short on 29 and 30 Dec; the planner offers 16-18 Dec instead. Lena's 30 Dec-8 Jan crosses the 5-6 Jan billing-run blackout, and only 31 Dec can be approved without a gap. Jonas's second trip needs 5 days with 4 left. Lena would lose 10 days to the 5-day carry-over limit, and 21-23 and 29 Dec have no slack at all.

## Rules

- Check coverage by role with one person per slot, not by headcount alone.
- Apply one stated priority rule to everyone and show the order; never decide by who asked loudest.
- Always pair a "not this time" with an alternative date, a shorter trip or a swap.
- Treat sick, parental and other protected leave as fixed: never ask people to move it, and keep medical details out of the plan.
- Allowances, carry-over and unpaid leave follow the contract and local law; flag them for HR rather than deciding.
- Share the plan only with the team and managers who need it.
FILE:references/coverage-rules.md
# Coverage rules

## Minimums
- Set a minimum per **role** (what must be covered: lead/approver, tier 2, on-call, pharmacist, key holder, forklift licence) and an **any** total (enough hands for the volume).
- Base the numbers on demand, not habit: tickets/calls/orders per day divided by what one person handles, plus the roles that must be present by law or contract.
- Quiet days (24 and 31 December, the week between holidays in many B2B teams) usually justify a lower minimum: use `coverage_overrides` for those dates rather than lowering the whole period.
- Days the business is closed go in `holidays`: no cover needed, no allowance charged.

## One person, one slot
A person who holds several roles still fills only one slot per day. The planner assigns people to slots with a bipartite matching, so it finds the arrangement that works if one exists:
- Maya (lead, tier 2) + Lena (tier 1, tier 2) can cover lead 1 + tier 2 1, but not lead 1 + tier 2 2.
- Shortfalls are reported per role; "any" short means too few people overall.

## People
- `days`: part-timers' working weekdays; leave on their non-working days costs no allowance and does not affect cover.
- Half days (`half_day=yes`) cost 0.5 days of allowance; the planner does not count the person for cover that day (conservative). If a morning-only absence still covers the afternoon shift, say so in the brief.
- Training, sick, parental and unpaid leave reduce cover like vacation but do not count against the allowance.

## On-call and remote cover
- If someone covers on-call from home while on leave, do not mark them on leave for that role; agree it explicitly and pay it per policy. The planner treats leave as fully off.
- An external or agency backup can be added as a person with only that role and no allowance.

## Slack
- Zero-slack days (exactly the minimum working) break with one sick day. Name a backup for each such day before the period starts.
- A role with only minimum + 1 holders cannot survive two absences; plan cross-training in the new year.
FILE:references/fair-leave-policy.md
# Fair leave decisions

## Priority rule (state it before the requests come in)
Common, defensible order:
1. Already approved leave stands (unless the person agrees to change it).
2. Protected leave (parental, medical, statutory) is fixed.
3. For peak days: people who worked the peak last year go first.
4. Then first come, first served by submission date.
5. Ties: rotate (whoever lost the last tie wins this one).
Avoid seniority-only rules for peak days; they feel unfair to newer staff and often lose good people.

## Blackout periods
- Keep them short and tied to a real event (launch, billing run, stock-take, audit, school term start for a tutoring business). Announce them early.
- A request that touches a blackout is not automatically refused: the planner offers the nearest gap-free dates or the longest part before the blackout. Exceptions need a named approver.

## Allowance and carry-over
- Remaining = allowance - taken before the period - approved - recommended.
- Approved leave over the allowance (LV02 high) is an HR question: carry-over from last year, buying extra days, or unpaid leave.
- Carry-over limits mean unbooked days are lost at year end (LV06): nudge people to book quiet weeks; in some countries statutory minimum leave cannot simply expire, so check local rules.

## Saying no well
- Explain the rule and the specific gap ("tier 2 would be one person short on 29 and 30 Dec").
- Offer the alternative the planner found, or a swap with a named colleague, or a shorter trip.
- Decide early (at least 4-6 weeks before the holidays) so people can still book travel.
- Record the decision and the reason; next year's priority depends on it.

## Finding codes (leave_cover.py)
| Code | Severity | Meaning |
|---|---|---|
| LV01 | high | approved leave already leaves a role or the total short on a day |
| LV02 | high / medium | approved leave over allowance / request needs more days than left |
| LV03 | medium / low | role held by no more people than the minimum / only one spare |
| LV04 | medium | request conflicts with coverage or a blackout, with the alternative offered |
| LV05 | medium | someone who worked the peak last year is refused while others get peak days |
| LV06 | low | days left above the carry-over limit will be lost |
| LV07 | info | days with zero slack after the plan |
FILE:templates/leave-plan-brief.md
# Holiday leave plan: <team>, <period>

**Cover rule:** <lead 1, tier 2 2 (1 on 24/31 Dec), on-call 1, at least 4 people>   **Closed:** <25 Dec, 28 Dec, 1 Jan>
**Priority used:** <worked the peak last year first, then first come first served>
**Blackout:** <5-6 Jan billing run>

## Decisions
| Person | Asked for | Decision | Why | Alternative offered |
|---|---|---|---|---|
| <Sam> | <24 Dec - 4 Jan> | <approved> | <worked last Christmas> | - |
| <Ade> | <29-31 Dec> | <not these dates> | <tier 2 short 29-30 Dec> | <16-18 Dec, or swap with ...> |

## Calendar
```
<paste the planner grid>
```

## Thin days and backups
| Day | Why thin | Backup |
|---|---|---|
| <21-23 Dec> | <exactly 4 working> | <on-call from home: ...> |

## Allowance notes (for HR)
- <Omar: approved trip 3 days over allowance - confirm carry-over / unpaid>
- <Lena: 15 days left, carry-over limit 5 - suggest booking February>

## Next steps
- <talk to Ade, Lena, Jonas before publishing>
- <publish the plan on ...; changes by swap request to ...>
- <cross-train a second lead backup in Q1>
FILE:examples/support-team.json
{
  "team": "Northwind Customer Support",
  "period": "2026-12-14..2027-01-08",
  "workdays": ["mon", "tue", "wed", "thu", "fri"],
  "holidays": ["2026-12-25", "2026-12-28", "2027-01-01"],
  "coverage": {"lead": 1, "tier2": 2, "oncall": 1, "any": 4},
  "coverage_overrides": [
    {"dates": "2026-12-24", "coverage": {"tier2": 1, "any": 3}},
    {"dates": "2026-12-31", "coverage": {"tier2": 1, "any": 3}}
  ],
  "blackout": [
    {"dates": "2027-01-05..2027-01-06", "reason": "January billing run, all hands"}
  ],
  "peak_days": "2026-12-21..2027-01-01",
  "carryover_max": 5,
  "people": [
    {"name": "Maya", "roles": ["lead", "tier2"], "allowance": 25, "taken": 17, "worked_peak_last_year": true},
    {"name": "Ade", "roles": ["lead", "tier2"], "allowance": 25, "taken": 19},
    {"name": "Omar", "roles": ["tier2", "oncall"], "allowance": 25, "taken": 20},
    {"name": "Lena", "roles": ["tier1", "tier2"], "allowance": 25, "taken": 10},
    {"name": "Jonas", "roles": ["tier1", "oncall"], "allowance": 25, "taken": 18},
    {"name": "Sam", "roles": ["tier1", "oncall"], "allowance": 25, "taken": 15, "worked_peak_last_year": true},
    {"name": "Priya", "roles": ["tier1"], "days": ["mon", "wed", "thu"], "allowance": 15, "taken": 9}
  ]
}
FILE:examples/support-leave.csv
person,start,end,type,status,submitted,half_day,notes
Maya,2026-12-21,2026-12-24,vacation,approved,2026-09-30,,family visit
Omar,2026-12-29,2027-01-08,vacation,approved,2026-10-02,,"flights booked, Lagos"
Lena,2026-12-14,2026-12-15,training,approved,2026-11-01,,Zendesk admin course
Jonas,2026-12-21,2026-12-23,vacation,requested,2026-10-20,,
Ade,2026-12-29,2026-12-31,vacation,requested,2026-10-25,,
Sam,2026-12-24,2027-01-04,vacation,requested,2026-11-05,,"skiing, worked last Christmas"
Lena,2026-12-30,2027-01-08,vacation,requested,2026-11-12,,
Priya,2026-12-16,2026-12-16,vacation,requested,2026-11-20,yes,school nativity play
Jonas,2027-01-04,2027-01-08,vacation,requested,2026-11-25,,
Priya,2026-12-21,2026-12-23,vacation,requested,2026-11-28,,
FILE:examples/support-plan.md
# Leave coverage plan: Northwind Customer Support (2026-12-14 to 2027-01-08)

Minimum cover per workday: any 4, lead 1, oncall 1, tier2 2.  Holidays (closed): 25 Dec, 28 Dec, 01 Jan.

**Verdict: over allowance on approved leave** - 4 of 7 open requests can be approved without a gap; 3 need a decision.

## Requests (in decision order: worked peak last year first, then first come first served)

| # | Person | Dates | Workdays | Type | Submitted | Decision | Why | Alternative |
|---|---|---|---|---|---|---|---|---|
| 1 | Sam | Thu 24 Dec - Mon 04 Jan | 5 | vacation | 2026-11-05 | approve | - | - |
| 2 | Jonas | Mon 21 Dec - Wed 23 Dec | 3 | vacation | 2026-10-20 | approve | - | - |
| 3 | Ade | Tue 29 Dec - Thu 31 Dec | 3 | vacation | 2026-10-25 | conflict | any/tier2 short on 29 Dec, 30 Dec | Wed 16 Dec to Fri 18 Dec |
| 4 | Lena | Wed 30 Dec - Fri 08 Jan | 7 | vacation | 2026-11-12 | blackout | January billing run, all hands (05 Jan, 06 Jan) | shorten to Thu 31 Dec - Thu 31 Dec (1 workday(s), back before the blackout) |
| 5 | Priya | Wed 16 Dec - Wed 16 Dec (half) | 0.5 | vacation | 2026-11-20 | approve | - | - |
| 6 | Jonas | Mon 04 Jan - Fri 08 Jan | 5 | vacation | 2026-11-25 | over allowance | needs 5 days, 4 left | - |
| 7 | Priya | Mon 21 Dec - Wed 23 Dec | 2 | vacation | 2026-11-28 | approve | - | - |

## Calendar (approved + recommended)

```
              D             J     
              11111222222233000000
              45678123458901145678
              MTWTFMTWTFMTWTFMTWTF
Maya          .....VVVVHH...H.....
Ade           .........HHxxxH.....
Omar          .........HHVVVHVVVVV
Lena          TT.......HH.xxHxxxxx
Jonas         .....vvv.HH...Hxxxxx
Sam           ........vHHvvvHv....
Priya         .-h.-v-v.HH-..H.-..-
cover any     +++++++++  +++ +++++
cover lead    +++++++++  +++ +++++
cover oncall  +++++++++  +++ +++++
cover tier2   +++++++++  +++ +++++
```
V/T/S/P/U/O approved vacation/training/sick/parental/unpaid/other, lowercase = request recommended for approval, h = half day, x = request not approved, H = holiday, - = not a working day, + / ! = role covered / short.

## Allowance (days)

| Person | Allowance | Taken before | Approved here | Recommended | Left | Peak days off |
|---|---|---|---|---|---|---|
| Maya | 25 | 17 | 4 | 0 | 4 | 4 |
| Ade | 25 | 19 | 0 | 0 | 6 | 0 |
| Omar | 25 | 20 | 8 | 0 | -3 | 3 |
| Lena | 25 | 10 | 0 | 0 | 15 | 0 |
| Jonas | 25 | 18 | 0 | 3 | 4 | 3 |
| Sam | 25 | 15 | 0 | 5 | 5 | 4 |
| Priya | 15 | 9 | 0 | 2.5 | 3.5 | 2 |

## Findings

- **HIGH LV02** Omar's approved leave exceeds the allowance by 3 days (20 + 8 taken of 25); confirm carry-over or unpaid leave with HR.
- **MEDIUM LV02** Jonas 04 Jan-08 Jan: needs 5 days, 4 left; approve a shorter trip or agree unpaid days
- **MEDIUM LV04** Ade 29 Dec-31 Dec: conflict (any/tier2 short on 29 Dec, 30 Dec); offer Wed 16 Dec to Fri 18 Dec
- **MEDIUM LV04** Lena 30 Dec-08 Jan: blackout (January billing run, all hands (05 Jan, 06 Jan)); offer shorten to Thu 31 Dec - Thu 31 Dec (1 workday(s), back before the blackout)
- **LOW LV03** lead has one spare person (Maya, Ade for a minimum of 1); two absences at once break it.
- **LOW LV06** Ade will still have 6 days left (carry-over limit 5); 1 day(s) are lost unless booked.
- **LOW LV06** Lena will still have 15 days left (carry-over limit 5); 10 day(s) are lost unless booked.
- **INFO LV07** No slack on 4 day(s) (21 Dec, 22 Dec, 23 Dec, 29 Dec): one sick day breaks coverage; line up a backup.
FILE:scripts/leave_cover.py
#!/usr/bin/env python3
"""Team leave and holiday coverage planner (Python 3.8+ standard library only).

Checks a team's leave requests against minimum staffing rules day by day, decides which
requests can be approved without leaving a gap, suggests alternative dates for the rest, and
tracks allowances and who gets the peak holiday days.

Team JSON:
{
  "team": "Support Desk", "period": "2026-12-14..2027-01-08",
  "workdays": ["mon", "tue", "wed", "thu", "fri"],
  "holidays": ["2026-12-25", "2026-12-28", "2027-01-01"],          (office closed, no coverage needed)
  "coverage": {"lead": 1, "tier2": 2, "oncall": 1, "any": 4},     ("any" = total people working)
  "coverage_overrides": [{"dates": "2026-12-24", "coverage": {"tier2": 1, "any": 3}}],
  "blackout": [{"dates": "2027-01-05..2027-01-06", "reason": "billing run"}],
  "peak_days": "2026-12-21..2027-01-01",
  "people": [
    {"name": "Maya", "roles": ["lead", "tier2"], "allowance": 25, "taken": 17, "worked_peak_last_year": true},
    {"name": "Priya", "roles": ["tier1"], "days": ["mon", "wed", "thu"], "allowance": 15, "taken": 9}
  ]
}
Each working person fills ONE role slot per day (a lead who is also tier2 counts once), solved
as a bipartite matching.

Leave CSV (header required): person,start,end,type,status,submitted,half_day,notes
  type     vacation (counts against allowance) | sick | training | parental | unpaid | other
  status   approved | requested | declined (ignored)
  half_day yes = half a day of allowance; the person is not counted for coverage that day

Usage:
  python3 leave_cover.py team.json leave.csv [--json]
  python3 leave_cover.py --self-test
Exit codes: 0 = approved leave keeps coverage and nobody is over allowance, 1 = approved leave
already breaks coverage or exceeds an allowance, 2 = bad input.
"""
import argparse
import csv
import datetime as dt
import json
import sys
from collections import OrderedDict, defaultdict

DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
TYPE_CODE = {"vacation": "V", "sick": "S", "training": "T", "parental": "P", "unpaid": "U", "other": "O"}


class InputError(ValueError):
    pass


def d(s, what="date"):
    try:
        return dt.date.fromisoformat(str(s).strip())
    except ValueError:
        raise InputError("%s %r is not YYYY-MM-DD" % (what, s))


def date_range(spec):
    spec = str(spec)
    a, _, b = spec.partition("..")
    a, b = d(a), d(b or a)
    if b < a:
        raise InputError("range %r ends before it starts" % spec)
    return [a + dt.timedelta(days=i) for i in range((b - a).days + 1)]


# ----------------------------------------------------------------------------- inputs
def load_team(cfg):
    if "period" not in cfg or not cfg.get("people"):
        raise InputError("team JSON needs 'period' and 'people'")
    t = dict(cfg)
    t["days"] = date_range(cfg["period"])
    t["workdays"] = [w.lower()[:3] for w in cfg.get("workdays", DAYS[:5])]
    t["holidays"] = {d(h, "holiday") for h in cfg.get("holidays", [])}
    t["coverage"] = {k: int(v) for k, v in (cfg.get("coverage") or {}).items()}
    over = {}
    for o in cfg.get("coverage_overrides", []):
        for day in date_range(o["dates"]):
            over[day] = {k: int(v) for k, v in o["coverage"].items()}
    t["overrides"] = over
    t["blackout"] = [(set(date_range(b["dates"])), b.get("reason", "blackout")) for b in cfg.get("blackout", [])]
    t["peak"] = set(date_range(cfg["peak_days"])) if cfg.get("peak_days") else set()
    people = OrderedDict()
    for p in cfg["people"]:
        if "name" not in p:
            raise InputError("every person needs a name")
        q = dict(p)
        q["roles"] = list(p.get("roles", []))
        q["days"] = [w.lower()[:3] for w in p.get("days", t["workdays"])]
        q["allowance"] = float(p.get("allowance", 0))
        q["taken"] = float(p.get("taken", 0))
        q["carryover_max"] = p.get("carryover_max", cfg.get("carryover_max"))
        people[p["name"]] = q
    t["people"] = people
    roles = {r for p in people.values() for r in p["roles"]}
    for r in list(t["coverage"]) + [r for o in over.values() for r in o]:
        if r != "any" and r not in roles:
            raise InputError("coverage role %r is not held by anyone" % r)
    return t


def load_leave(path, team):
    out = []
    with open(path, newline="", encoding="utf-8") as f:
        rows = [r for r in f if r.strip() and not r.lstrip().startswith("#")]
    for n, row in enumerate(csv.DictReader(rows), 2):
        name = (row.get("person") or "").strip()
        if name not in team["people"]:
            raise InputError("leave line %d: unknown person %r" % (n, name))
        typ = (row.get("type") or "vacation").strip().lower()
        if typ not in TYPE_CODE:
            raise InputError("leave line %d: type must be one of %s" % (n, ", ".join(TYPE_CODE)))
        status = (row.get("status") or "requested").strip().lower()
        if status not in ("approved", "requested", "declined"):
            raise InputError("leave line %d: status must be approved, requested or declined" % n)
        start, end = d(row.get("start"), "start"), d(row.get("end") or row.get("start"), "end")
        if end < start:
            raise InputError("leave line %d: end before start" % n)
        out.append({"id": n, "person": name, "start": start, "end": end, "type": typ, "status": status,
                    "submitted": (row.get("submitted") or "").strip() or "9999-12-31",
                    "half": (row.get("half_day") or "").strip().lower() in ("yes", "y", "true", "1"),
                    "notes": (row.get("notes") or "").strip()})
    return out


# ----------------------------------------------------------------------------- core
def is_workday(team, day):
    return DAYS[day.weekday()] in team["workdays"] and day not in team["holidays"]


def person_works(team, p, day):
    return is_workday(team, day) and DAYS[day.weekday()] in p["days"]


def leave_days(team, lv):
    p = team["people"][lv["person"]]
    days = []
    cur = lv["start"]
    while cur <= lv["end"]:
        if person_works(team, p, cur):
            days.append(cur)
        cur += dt.timedelta(days=1)
    return days


def charge(team, lv):
    n = len(leave_days(team, lv))
    return 0.5 * n if lv["half"] else float(n)


def need_for(team, day):
    need = dict(team["coverage"])
    need.update(team["overrides"].get(day, {}))
    return need


def shortfall(team, day, off):
    """Return {role: missing} for one day given the set of people off."""
    if not is_workday(team, day):
        return {}
    avail = [p for n, p in team["people"].items() if n not in off and person_works(team, p, day)]
    need = need_for(team, day)
    slots = [r for r, k in sorted(need.items()) if r != "any" for _ in range(k)]
    match = {}  # slot index -> person name

    def try_assign(pi, seen):
        for si, role in enumerate(slots):
            if role in avail[pi]["roles"] and si not in seen:
                seen.add(si)
                if si not in match or try_assign(match[si], seen):
                    match[si] = pi
                    return True
        return False

    for pi in range(len(avail)):
        try_assign(pi, set())
    short = defaultdict(int)
    for si, role in enumerate(slots):
        if si not in match:
            short[role] += 1
    if need.get("any", 0) > len(avail):
        short["any"] = need["any"] - len(avail)
    return dict(short)


def off_map(team, leaves):
    off = defaultdict(set)
    for lv in leaves:
        for day in leave_days(team, lv):
            off[day].add(lv["person"])
    return off


def gaps(team, leaves):
    off = off_map(team, leaves)
    out = OrderedDict()
    for day in team["days"]:
        s = shortfall(team, day, off.get(day, set()))
        if s:
            out[day] = s
    return out


def total(g):
    return sum(sum(v.values()) for v in g.values())


def new_gaps(before, after):
    out = OrderedDict()
    for day, s in after.items():
        b = before.get(day, {})
        worse = {r: k - b.get(r, 0) for r, k in s.items() if k > b.get(r, 0)}
        if worse:
            out[day] = worse
    return out


def blackout_hit(team, lv):
    days = set(leave_days(team, lv))
    for bdays, reason in team["blackout"]:
        hit = sorted(days & bdays)
        if hit:
            return hit, reason
    return None, None


def suggest(team, current, lv, max_shift=15):
    """Nearest shift of the same request (same calendar length) that keeps coverage."""
    length = (lv["end"] - lv["start"]).days
    want = len(leave_days(team, lv))
    base = gaps(team, current)
    first, last = team["days"][0], team["days"][-1]
    for shift in sorted(range(-max_shift, max_shift + 1), key=lambda x: (abs(x), x)):
        if shift == 0:
            continue
        cand = dict(lv, start=lv["start"] + dt.timedelta(days=shift), end=lv["start"] + dt.timedelta(days=shift + length))
        if cand["start"] < first or cand["end"] > last:
            continue
        if len(leave_days(team, cand)) < want or blackout_hit(team, cand)[0]:
            continue
        if not new_gaps(base, gaps(team, current + [cand])):
            return cand
    return None


def trimmed(team, current, lv):
    """Longest part of a blackout-hitting request, before the first blackout day, that keeps coverage."""
    hit, _ = blackout_hit(team, lv)
    days = [x for x in leave_days(team, lv) if x < hit[0]]
    base = gaps(team, current)
    best = None
    for i in range(len(days)):
        for j in range(len(days) - 1, i - 1, -1):
            if best and j - i + 1 <= len(leave_days(team, best)):
                break
            cand = dict(lv, start=days[i], end=days[j])
            if not new_gaps(base, gaps(team, current + [cand])):
                best = cand
                break
    return best


def plan(team, leaves):
    findings = []

    def add(sev, code, msg):
        findings.append({"severity": sev, "code": code, "message": msg})

    approved = [l for l in leaves if l["status"] == "approved"]
    requests = [l for l in leaves if l["status"] == "requested"]
    used = defaultdict(float)
    for l in approved:
        if l["type"] == "vacation":
            used[l["person"]] += charge(team, l)

    g_approved = gaps(team, approved)
    for day, s in g_approved.items():
        add("high", "LV01", "%s %s: approved leave already leaves %s short" % (
            day.isoformat(), DAYS[day.weekday()].title(), ", ".join("%s by %d" % (r, k) for r, k in sorted(s.items()))))

    def priority(l):
        p = team["people"][l["person"]]
        touches_peak = bool(set(leave_days(team, l)) & team["peak"])
        return (0 if touches_peak and p.get("worked_peak_last_year") else 1, l["submitted"], l["id"])

    current = list(approved)
    decisions = []
    for l in sorted(requests, key=priority):
        p = team["people"][l["person"]]
        days = leave_days(team, l)
        c = charge(team, l) if l["type"] == "vacation" else 0.0
        dec = {"leave": l, "workdays": len(days), "charge": c, "decision": "approve", "reason": "", "suggestion": None}
        if not days:
            dec.update(decision="no workdays", reason="falls on holidays / non-working days only")
        elif l["type"] == "vacation" and p["allowance"] and p["taken"] + used[l["person"]] + c > p["allowance"] + 1e-9:
            left = p["allowance"] - p["taken"] - used[l["person"]]
            dec.update(decision="over allowance", reason="needs %g days, %g left" % (c, max(left, 0)))
        else:
            hit, reason = blackout_hit(team, l)
            if hit:
                dec.update(decision="blackout", reason="%s (%s)" % (reason, ", ".join(x.strftime("%d %b") for x in hit)))
            else:
                ng = new_gaps(gaps(team, current), gaps(team, current + [l]))
                if ng:
                    roles = sorted({r for s in ng.values() for r in s})
                    dec.update(decision="conflict", reason="%s short on %s" % (
                        "/".join(roles), ", ".join(x.strftime("%d %b") for x in ng)))
        if dec["decision"] == "approve":
            current.append(l)
            used[l["person"]] += c
        elif dec["decision"] in ("conflict", "blackout"):
            s = suggest(team, current, l)
            if s:
                dec["suggestion"] = "%s to %s" % (s["start"].strftime("%a %d %b"), s["end"].strftime("%a %d %b"))
            elif dec["decision"] == "blackout":
                t = trimmed(team, current, l)
                if t:
                    dec["suggestion"] = "shorten to %s - %s (%d workday(s), back before the blackout)" % (
                        t["start"].strftime("%a %d %b"), t["end"].strftime("%a %d %b"), len(leave_days(team, t)))
        decisions.append(dec)

    approved_peak = defaultdict(int)
    for l in current:
        approved_peak[l["person"]] += len(set(leave_days(team, l)) & team["peak"])
    for dec in decisions:
        l = dec["leave"]
        p = team["people"][l["person"]]
        if dec["decision"] != "approve" and p.get("worked_peak_last_year") and set(leave_days(team, l)) & team["peak"]:
            lucky = [n for n, k in approved_peak.items() if k and not team["people"][n].get("worked_peak_last_year")]
            add("medium", "LV05", "%s worked the peak last year but this request is %s while %s get peak days off; "
                "consider swapping." % (l["person"], dec["decision"], ", ".join(sorted(lucky)) or "nobody"))

    g_final = gaps(team, current)
    allowance = []
    for n, p in team["people"].items():
        planned_req = sum(dec["charge"] for dec in decisions if dec["leave"]["person"] == n and dec["decision"] == "approve")
        appr = used[n] - planned_req
        left = p["allowance"] - p["taken"] - used[n] if p["allowance"] else None
        allowance.append({"person": n, "allowance": p["allowance"], "taken_before": p["taken"], "approved": appr,
                          "recommended": planned_req, "left": left, "peak_days_off": approved_peak.get(n, 0)})
        if p["allowance"] and p["taken"] + appr > p["allowance"] + 1e-9:
            add("high", "LV02", "%s's approved leave exceeds the allowance by %g days (%g + %g taken of %g); "
                "confirm carry-over or unpaid leave with HR." % (n, p["taken"] + appr - p["allowance"], p["taken"],
                                                               appr, p["allowance"]))
        cm = p.get("carryover_max")
        if left is not None and cm is not None and left > float(cm):
            add("low", "LV06", "%s will still have %g days left (carry-over limit %g); %g day(s) are lost unless booked."
                % (n, left, float(cm), left - float(cm)))

    for role, k in sorted(team["coverage"].items()):
        if role == "any":
            continue
        holders = [n for n, p in team["people"].items() if role in p["roles"]]
        if len(holders) <= k:
            add("medium", "LV03", "Only %d people can cover %s (minimum %d): any absence by %s breaks coverage; "
                "cross-train a backup." % (len(holders), role, k, ", ".join(holders)))
        elif len(holders) == k + 1:
            add("low", "LV03", "%s has one spare person (%s for a minimum of %d); two absences at once break it."
                % (role, ", ".join(holders), k))
    for day, s in g_final.items():
        if day not in g_approved:
            add("high", "LV01", "%s still short after decisions: %s" % (day, s))
    for dec in decisions:
        if dec["decision"] in ("conflict", "blackout"):
            l = dec["leave"]
            add("medium", "LV04", "%s %s-%s: %s (%s)%s" % (
                l["person"], l["start"].strftime("%d %b"), l["end"].strftime("%d %b"), dec["decision"], dec["reason"],
                ("; offer " + dec["suggestion"]) if dec["suggestion"] else "; no gap-free alternative within 15 days"))
        elif dec["decision"] == "over allowance":
            l = dec["leave"]
            add("medium", "LV02", "%s %s-%s: %s; approve a shorter trip or agree unpaid days" % (
                l["person"], l["start"].strftime("%d %b"), l["end"].strftime("%d %b"), dec["reason"]))
    thin = []
    off = off_map(team, current)
    for day in team["days"]:
        if not is_workday(team, day):
            continue
        working = [n for n, p in team["people"].items() if n not in off.get(day, set()) and person_works(team, p, day)]
        if len(working) == need_for(team, day).get("any", 0):
            thin.append(day)
    if thin:
        add("info", "LV07", "No slack on %d day(s) (%s): one sick day breaks coverage; line up a backup." % (
            len(thin), ", ".join(x.strftime("%d %b") for x in thin)))
    order = {"high": 0, "medium": 1, "low": 2, "info": 3}
    findings.sort(key=lambda f: (order[f["severity"]], f["code"]))
    return {"team": team.get("team", "Team"), "period": team["period"], "gaps_approved": g_approved,
            "gaps_final": g_final, "decisions": decisions, "allowance": allowance, "findings": findings,
            "current": current, "thin": thin}


# ----------------------------------------------------------------------------- report
def grid(team, leaves_final, all_leaves):
    days = [x for x in team["days"] if x.weekday() < 5 or DAYS[x.weekday()] in team["workdays"]]
    final_ids = {l["id"] for l in leaves_final}
    cell = defaultdict(dict)
    for l in all_leaves:
        if l["status"] == "declined":
            continue
        for day in leave_days(team, l):
            if l["id"] in final_ids:
                c = TYPE_CODE[l["type"]] if l["status"] == "approved" else TYPE_CODE[l["type"]].lower()
            else:
                c = "x"
            if l["half"]:
                c = "h" if c != "x" else "x"
            cell[l["person"]][day] = c
    width = max([len(n) for n in team["people"]] + [len("cover " + r) for r in team["coverage"]]) + 2
    months = " " * width + "".join(x.strftime("%b")[0] if i == 0 or x.month != days[i - 1].month
                                   else " " for i, x in enumerate(days))
    L = [months, " " * width + "".join(str(x.day // 10) for x in days),
         " " * width + "".join(str(x.day % 10) for x in days),
         " " * width + "".join(DAYS[x.weekday()][0].upper() for x in days)]
    for n, p in team["people"].items():
        row = []
        for x in days:
            if x in team["holidays"]:
                row.append("H")
            elif not person_works(team, p, x):
                row.append("-")
            else:
                row.append(cell[n].get(x, "."))
        L.append(n.ljust(width) + "".join(row))
    off = off_map(team, leaves_final)
    for role in sorted(team["coverage"]):
        row = []
        for x in days:
            if not is_workday(team, x):
                row.append(" ")
                continue
            s = shortfall(team, x, off.get(x, set()))
            row.append("!" if role in s else "+")
        L.append(("cover " + role).ljust(width) + "".join(row))
    return L


def report(team, leaves, r):
    L = ["# Leave coverage plan: %s (%s)" % (r["team"], r["period"].replace("..", " to ")), ""]
    need = ", ".join("%s %d" % (k, v) for k, v in sorted(team["coverage"].items()))
    L.append("Minimum cover per workday: %s.  Holidays (closed): %s." % (
        need, ", ".join(x.strftime("%d %b") for x in sorted(team["holidays"])) or "none"))
    n_appr = sum(1 for dec in r["decisions"] if dec["decision"] == "approve")
    verdict = ("approved leave already breaks coverage" if r["gaps_approved"] else
               "over allowance on approved leave" if any(f["code"] == "LV02" and f["severity"] == "high" for f in r["findings"])
               else "covered")
    L += ["", "**Verdict: %s** - %d of %d open requests can be approved without a gap; %d need a decision." % (
        verdict, n_appr, len(r["decisions"]), len(r["decisions"]) - n_appr), ""]
    L += ["## Requests (in decision order: worked peak last year first, then first come first served)", "",
          "| # | Person | Dates | Workdays | Type | Submitted | Decision | Why | Alternative |",
          "|---|---|---|---|---|---|---|---|---|"]
    for i, dec in enumerate(r["decisions"], 1):
        l = dec["leave"]
        L.append("| %d | %s | %s - %s%s | %s | %s | %s | %s | %s | %s |" % (
            i, l["person"], l["start"].strftime("%a %d %b"), l["end"].strftime("%a %d %b"), " (half)" if l["half"] else "",
            ("%g" % (0.5 * dec["workdays"])) if l["half"] else dec["workdays"], l["type"], l["submitted"][:10],
            dec["decision"], dec["reason"] or "-", dec["suggestion"] or "-"))
    L += ["", "## Calendar (approved + recommended)", "", "```"] + grid(team, r["current"], leaves) + [
        "```", "V/T/S/P/U/O approved vacation/training/sick/parental/unpaid/other, lowercase = request recommended "
        "for approval, h = half day, x = request not approved, H = holiday, - = not a working day, "
        "+ / ! = role covered / short.", ""]
    L += ["## Allowance (days)", "", "| Person | Allowance | Taken before | Approved here | Recommended | Left | Peak days off |",
          "|---|---|---|---|---|---|---|"]
    for a in r["allowance"]:
        L.append("| %s | %g | %g | %g | %g | %s | %d |" % (a["person"], a["allowance"], a["taken_before"], a["approved"],
                                                          a["recommended"], "-" if a["left"] is None else "%g" % a["left"],
                                                          a["peak_days_off"]))
    L += ["", "## Findings", ""]
    if not r["findings"]:
        L.append("- none")
    for f in r["findings"]:
        L.append("- **%s %s** %s" % (f["severity"].upper(), f["code"], f["message"]))
    return "\n".join(L) + "\n"


# ----------------------------------------------------------------------------- self-test
def self_test():
    import os
    import tempfile
    cases = []

    def ok(name, cond, detail=""):
        cases.append((name, bool(cond), detail))

    base = {"team": "T", "period": "2026-12-14..2026-12-25", "holidays": ["2026-12-25"], "peak_days": "2026-12-21..2026-12-24",
            "coverage": {"lead": 1, "dev": 1, "any": 2},
            "people": [{"name": "A", "roles": ["lead", "dev"], "allowance": 10, "taken": 0},
                       {"name": "B", "roles": ["dev"], "allowance": 10, "taken": 9},
                       {"name": "C", "roles": ["lead"], "allowance": 10, "taken": 0, "worked_peak_last_year": True},
                       {"name": "D", "roles": ["dev"], "days": ["mon", "tue"], "allowance": 5, "taken": 0}]}
    t = load_team(base)
    ok("weekends and holidays are not workdays", not is_workday(t, d("2026-12-19")) and not is_workday(t, d("2026-12-25")))
    sf = shortfall(t, d("2026-12-16"), {"B", "C", "D"})
    ok("one person fills one slot (A cannot be lead and dev)", sf.get("any") == 1 and sf.get("lead", 0) + sf.get("dev", 0) == 1, sf)
    ok("matching finds A=dev, C=lead", shortfall(t, d("2026-12-16"), {"B", "D"}) == {})
    ok("part-timer only counts on own days", shortfall(t, d("2026-12-17"), {"A", "B"}) == {"dev": 1, "any": 1}, shortfall(t, d("2026-12-17"), {"A", "B"}))
    lv = {"id": 1, "person": "D", "start": d("2026-12-14"), "end": d("2026-12-20"), "type": "vacation",
          "status": "requested", "submitted": "2026-11-01", "half": False, "notes": ""}
    ok("leave days skip non-working days", len(leave_days(t, lv)) == 2)
    ok("half day charges 0.5", charge(t, dict(lv, half=True)) == 1.0)

    d0 = tempfile.mkdtemp()
    csvp = os.path.join(d0, "l.csv")
    with open(csvp, "w") as f:
        f.write("person,start,end,type,status,submitted,half_day,notes\n"
                "A,2026-12-21,2026-12-22,vacation,approved,2026-10-01,,\n"
                "C,2026-12-21,2026-12-21,vacation,requested,2026-11-10,,\n"
                "B,2026-12-14,2026-12-16,vacation,requested,2026-10-05,,\n"
                "D,2026-12-15,2026-12-15,training,requested,2026-11-01,,\n")
    leaves = load_leave(csvp, t)
    r = plan(t, leaves)
    by = {(dec["leave"]["person"]): dec for dec in r["decisions"]}
    ok("C conflicts with A's approved leave (no lead)", by["C"]["decision"] == "conflict", by["C"])
    ok("conflict gets an alternative date", by["C"]["suggestion"] is not None, by["C"])
    ok("B over allowance (3 days, 1 left)", by["B"]["decision"] == "over allowance", by["B"])
    ok("D training approved", by["D"]["decision"] == "approve", by["D"])
    ok("worked-peak person decided first", r["decisions"][0]["leave"]["person"] == "C", [x["leave"]["person"] for x in r["decisions"]])
    codes = {f["code"] for f in r["findings"]}
    ok("LV03 single point of failure for lead", "LV03" in codes, codes)
    ok("LV05 fairness flag for C", "LV05" in codes, codes)
    ok("no gaps from approved leave", not r["gaps_approved"])
    with open(csvp, "a") as f:
        f.write("C,2026-12-21,2026-12-21,sick,approved,2026-12-01,,\n")
    r2 = plan(t, load_leave(csvp, t))
    ok("LV01 gap in approved leave", any(f["code"] == "LV01" and f["severity"] == "high" for f in r2["findings"]))
    t2 = load_team(dict(base, blackout=[{"dates": "2026-12-16", "reason": "release"}]))
    r3 = plan(t2, load_leave(csvp, t2))
    ok("blackout precedes coverage", any(x["decision"] == "blackout" for x in r3["decisions"]) or
       all(x["leave"]["person"] != "B" or x["decision"] == "over allowance" for x in r3["decisions"]))
    lvb = dict(lv, person="A", start=d("2026-12-16"), end=d("2026-12-16"))
    ok("blackout_hit detects overlap", blackout_hit(t2, lvb)[0] == [d("2026-12-16")])
    try:
        load_team(dict(base, coverage={"qa": 1}))
        ok("unknown coverage role rejected", False)
    except InputError:
        ok("unknown coverage role rejected", True)
    rep = report(t, leaves, r)
    ok("report has grid and verdict", "Verdict" in rep and "cover lead" in rep)

    for name, good, detail in cases:
        print("%s  %s%s" % ("PASS" if good else "FAIL", name, "" if good else "  -> %r" % (detail,)))
    passed = sum(1 for _, g, _ in cases if g)
    print("%d/%d passed" % (passed, len(cases)))
    return 0 if passed == len(cases) else 1


def to_json(r):
    def conv(o):
        if isinstance(o, dt.date):
            return o.isoformat()
        if isinstance(o, dict):
            return {(k.isoformat() if isinstance(k, dt.date) else k): conv(v) for k, v in o.items()}
        if isinstance(o, (list, tuple)):
            return [conv(x) for x in o]
        return o
    return json.dumps(conv(r), indent=2)


def main(argv=None):
    ap = argparse.ArgumentParser(description="Plan team leave against minimum coverage.")
    ap.add_argument("team", nargs="?")
    ap.add_argument("leave", nargs="?")
    ap.add_argument("--json", action="store_true")
    ap.add_argument("--self-test", action="store_true")
    a = ap.parse_args(argv)
    if a.self_test:
        return self_test()
    if not (a.team and a.leave):
        ap.print_usage(sys.stderr)
        return 2
    try:
        with open(a.team, encoding="utf-8") as f:
            team = load_team(json.load(f))
        leaves = load_leave(a.leave, team)
        r = plan(team, leaves)
    except (InputError, OSError, json.JSONDecodeError, KeyError) as e:
        print("error: %s" % e, file=sys.stderr)
        return 2
    print(to_json(r) if a.json else report(team, leaves, r), end="\n" if a.json else "")
    bad = r["gaps_approved"] or any(f["code"] == "LV02" and f["severity"] == "high" for f in r["findings"])
    return 1 if bad else 0


if __name__ == "__main__":
    sys.exit(main())
HRManagementPlanning+2
F@f
0
New Hire First Week Onboarding Plan Builder (YAML)
Text

Turn notes about a new team member into a YAML first week onboarding plan: a pre-start checklist with owners, a welcome message, a day-by-day schedule with meeting limits, people to meet, access and equipment, a learning plan, a low-risk first contribution, a buddy guide, and feedback questions.

1role: Thoughtful people manager and onboarding designer for small and mid-sized teams
2task: >
3 Turn my notes about a new team member, their role, and my team into a complete first week
4 onboarding plan as YAML: preparation before day one, a day-by-day schedule, people to meet,
5 access and equipment, learning goals, a small first contribution, check-ins, and a simple
6 way to collect feedback, so the new hire feels welcome and productive without being overloaded.
7
8inputs:
9 new_hire_role: ${role:junior customer support specialist}
10 start_date_and_hours: ${start:Monday 09:00, full time, Monday to Friday}
...+80 more lines
YAMLOnboardingHR+2
F@f
0
Online Job Search Assistant
Text

Assists users in finding job opportunities online by identifying key skills, suggesting job portals, and providing application tips.

Act as a Job Search Assistant. You are an expert in online job searching with extensive knowledge of various job portals and platforms.

Your task is to assist users in finding suitable job opportunities that match their skills and preferences.

You will:
- Identify key skills and experiences from the user's profile.
- Suggest job portals and websites where these skills are in high demand.
- Search for the contact information of hiring managers.
- Curate a list of available jobs based on the user's profile.

Rules:
- Always respect user privacy and confidentiality.
- Provide accurate and up-to-date information.
- Tailor advice to the user's specified job sector and location preferences.
HRCareer
J@ia-kobos
0
Act as a Job Application Reviewer
Text

A prompt for reviewing job applications by comparing resumes with job descriptions to assess candidate suitability.

Act as a Job Application Reviewer. You are an experienced HR professional tasked with evaluating job applications.

Your task is to:
- Analyze the candidate's resume for key qualifications, skills, and experiences relevant to the job description provided.
- Compare the candidate's credentials with the job requirements to assess suitability.
- Provide constructive feedback on how well the candidate's profile matches the job role.
- Highlight specific points in the resume that need to be edited or removed to better align with the job description.
- Suggest additional points or improvements that could make the candidate a stronger applicant.

Rules:
- Focus on relevant work experience, skills, and accomplishments.
- Ensure the resume is aligned with the job description's requirements.
- Offer actionable suggestions for improvement, if necessary.

Variables:
- resume - The candidate's resume text
- jobDescription - The job description text
RecruitingResumeHR+1
K@vivianvivianraj
1
Dynamic Cover Letter Generator
Text

Generate a tailored cover letter using your CV and job description, formatted to fit one A4 page.

Act as a Professional Cover Letter Writer. You are an expert in crafting personalized cover letters that effectively showcase an applicant's qualifications and match them to a specific job description.

Your task is to write a personalized cover letter using the applicant's CV and the job description provided. Ensure the cover letter fits on one A4 page. Inspired by the model 1/polite salutation; 2/ synthetize presentation of the job ; 3/ personalized presentation of myself ; 4/ illustrate how my profile fits the job description and how we can work together ; 5/ polite invitation to meet + contact my references. 

You will:
- Analyze the provided CV and job description to extract relevant skills and experiences
- Highlight the applicant's most relevant qualifications and achievements
- Ensure the tone is professional and tailored to the job role

Rules:
- Maintain a formal and concise writing style
- Use the applicant's name and contact information as provided
- Address the cover letter to the hiring manager if possible

Variables:
- cvContent - Ask for a CV file
- jobDescription - Ask for a URL
- applicantName - Name of the applicant
- hiringComanyName - Name of the hiring company
CareerResumeHR
6@6tealeaf9
1
Structured Job Application Cleanup
Text

This prompt helps in cleaning and structuring job application content for AI analysis, focusing on clarity and key information extraction.

Act as a Job Application Cleaner. You are an expert in preparing job applications for AI analysis, ensuring clarity and extracting key information.

Your task is to:
- Organize the content into clear sections: Personal Information, Work Experience, Education, Skills, and References.
- Ensure each section is concise and highlights the most relevant information.
- Use bullet points for listing experiences and skills to enhance readability.
- Highlight keywords that are crucial for job matching and AI parsing.

Rules:
- Maintain a professional tone throughout.
- Do not alter factual information; focus on format and clarity.
- Use consistent formatting for dates and titles.
ResumeHRCareer
A@axusmawesuper
0
Act as a Resume Reviewer for Anthropic Fellows Program
Text

A prompt for reviewing resumes for applicants to the Anthropic Fellows Program, focusing on AI safety research expertise and alignment.

Act as a Resume Reviewer. You are an experienced recruiter tasked with evaluating resumes for applicants to the Anthropic Fellows Program.

Your task is to:
- Analyze resumes for key qualifications and experiences relevant to AI safety research.
- Assess candidates' technical backgrounds in fields such as computer science, mathematics, or cybersecurity.
- Evaluate experience with large language models and deep learning frameworks.
- Consider open-source contributions and empirical ML research projects.
- Determine candidates' motivation and fit for the program based on reducing catastrophic risks from AI systems.

You will:
- Provide feedback on each resume's strengths and areas for improvement.
- Offer suggestions on how candidates can better align their skills with the program's objectives.

Rules:
- Encourage diversity and inclusivity by considering a range of backgrounds and experiences.
- Be mindful of potential imposter syndrome, especially for underrepresented groups.
RecruitingResumeHR+2
A@axusmawesuper
0
Act as a Resume Reviewer
Text

A prompt for reviewing resumes in the context of a specific job opening.

Act as a Resume Reviewer. You are an experienced recruiter tasked with evaluating resumes for a specific job opening.

Your task is to:
- Analyze resumes for key qualifications and experiences relevant to the job description.
- Provide constructive feedback on strengths and areas for improvement.
- Highlight discrepancies or concerns that may arise from the resume.

Rules:
- Focus on relevant skills and experiences.
- Maintain confidentiality of all information reviewed.

Variables:
- jobDescription - Specific details of the job opening.
- resume - The resume content to be reviewed.
RecruitingResumeHR+1
A@axusmawesuper
2
Universal Lead & Candidate Outreach Generator (HR, SALES)
Text

Master the art of turning raw LinkedIn data into high‑impact outreach. This prompt helps you qualify top prospects in HR or Sales and generate personalized messages at scale. For a quick test, upload a LinkedIn JSON profile and a job offer or service PDF, then let the system create conversion‑ready outreach you can replicate/scale across hundreds/thousands of profiles.

# **🔥 Universal Lead & Candidate Outreach Generator**  
### *AI Prompt for Automated Message Creation from LinkedIn JSON + PDF Offers*

---

## **🚀 Global Instruction for the Chatbot**

You are an AI assistant specialized in generating **high‑quality, personalized outreach messages** by combining structured LinkedIn data (JSON) with contextual information extracted from PDF documents.

You will receive:  
- **One or multiple LinkedIn profiles** in **JSON format** (candidates or sales prospects)  
- **One or multiple PDF documents**, which may contain:  
  - **Job descriptions** (HR use case)  
  - **Service or technical offering documents** (Sales use case)

Your mission is to produce **one tailored outreach message per profile**, each with a **clear, descriptive title**, and fully adapted to the appropriate context (HR or Sales).

---

## **🧩 High‑Level Workflow**

```
          ┌──────────────────────┐
          │  LinkedIn JSON File  │
          │ (Candidate/Prospect) │
          └──────────┬───────────┘
                     │ Extract
                     ▼
          ┌──────────────────────┐
          │  Profile Data Model  │
          │ (Name, Experience,   │
          │  Skills, Summary…)   │
          └──────────┬───────────┘
                     │
                     ▼
          ┌──────────────────────┐
          │     PDF Document     │
          │ (Job Offer / Sales   │
          │   Technical Offer)   │
          └──────────┬───────────┘
                     │ Extract
                     ▼
          ┌──────────────────────┐
          │   Opportunity Data   │
          │ (Company, Role,      │
          │  Needs, Benefits…)   │
          └──────────┬───────────┘
                     │
                     ▼
          ┌──────────────────────┐
          │ Personalized Message  │
          │   (HR or Sales)       │
          └──────────────────────┘
```

---

## **📥 1. Data Extraction Rules**

### **1.1 Extract Profile Data from JSON**
For each JSON file (e.g., `profile1.json`), extract at minimum:

- **First name** → `data.firstname`  
- **Last name** → `data.lastname`  
- **Professional experiences** → `data.experiences`  
- **Skills** → `data.skills`  
- **Current role** → `data.experiences[0]`  
- **Headline / summary** (if available)

> **Note:** Adapt the extraction logic to match the exact structure of your JSON/data model.

---

### **1.2 Extract Opportunity Data from PDF**

#### **HR – Job Offer PDF**
Extract:
- Company name  
- Job title  
- Required skills  
- Responsibilities  
- Location  
- Tech stack (if applicable)  
- Any additional context that helps match the candidate

#### **Sales – Service / Technical Offer PDF**
Extract:
- Company name  
- Description of the service  
- Pain points addressed  
- Value proposition  
- Technical scope  
- Pricing model (if present)  
- Call‑to‑action or next steps

---

## **🧠 2. Message Generation Logic**

### **2.1 One Message per Profile**
For each JSON file, generate a **separate, standalone message** with a clear title such as:

- **Candidate Outreach – firstname lastname**  
- **Sales Prospect Outreach – firstname lastname**

---

### **2.2 Universal Message Structure**

Each message must follow this structure:

---

### **1. Personalized Introduction**
Use the candidate/prospect’s full name.

**Example:**  
“Hello {data.firstname} {data.lastname},”

---

### **2. Highlight Relevant Experience**
Identify the most relevant experience based on the PDF content.

Include:
- Job title  
- Company  
- One key skill  

**Example:**  
“Your recent role as {data.experiences[0].title} at {data.experiences[0].subtitle.split('.')[0].trim()} particularly stood out, especially your expertise in {data.skills[0].title}.”

---

### **3. Present the Opportunity (HR or Sales)**

#### **HR Version (Candidate)**  
Describe:
- The company  
- The role  
- Why the candidate is a strong match  
- Required skills aligned with their background  
- Any relevant mission, culture, or tech stack elements  

#### **Sales Version (Prospect)**  
Describe:
- The service or technical offer  
- The prospect’s potential needs (inferred from their experience)  
- How your solution addresses their challenges  
- A concise value proposition  
- Why the timing may be relevant  

---

### **4. Call to Action**
Encourage a next step.

Examples:
- “I’d be happy to discuss this opportunity with you.”  
- “Feel free to book a slot on my Calendly.”  
- “Let’s explore how this solution could support your team.”

---

### **5. Closing & Contact Information**
End with:
- Appreciation  
- Contact details  
- Calendly link (if provided)

---

## **📨 3. Example Automated Message (HR Version)**

```
Title: Candidate Outreach – {data.firstname} {data.lastname}

Hello {data.firstname} {data.lastname},

Your impressive background, especially your current role as {data.experiences[0].title} at {data.experiences[0].subtitle.split(".")[0].trim()}, immediately caught our attention. Your expertise in {data.skills[0].title} aligns perfectly with the key skills required for this position.

We would love to introduce you to the opportunity: job_title, based in location. This role focuses on functional_responsibilities, and the technical environment includes tech_stack. The company company_name is known for short_description.

We would be delighted to discuss this opportunity with you in more detail.  
You can apply directly here: job_link or schedule a call via Calendly: calendly_link.

Looking forward to speaking with you,  
recruiter_name  
company_name
```

---

## **📨 4. Example Automated Message (Sales Version)**

```
Title: Sales Prospect Outreach – {data.firstname} {data.lastname}

Hello {data.firstname} {data.lastname},

Your experience as {data.experiences[0].title} at {data.experiences[0].subtitle.split(".")[0].trim()} stood out to us, particularly your background in {data.skills[0].title}. Based on your profile, it seems you may be facing challenges related to pain_point_inferred_from_pdf.

We are currently offering a technical intervention service: service_name. This solution helps companies like yours by value_proposition, and covers areas such as technical_scope_extracted_from_pdf.

I would be happy to explore how this could support your team’s objectives.  
Feel free to book a meeting here: calendly_link or reply directly to this message.

Best regards,  
sales_representative_name  
company_name
```

---

## **📈 5. Notes for Scalability**
- The offer description can be **generic or specific**, depending on the PDF.  
- The tone must remain **professional, concise, and personalized**.  
- Automatically adapt the message to the **HR** or **Sales** context based on the PDF content.  
- Ensure consistency across multiple profiles when generating messages in bulk.

HRSalesMarketing+3
N@nnassili-z0
1