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…
---
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"출처 · prompts.chat 공개 프롬프트 모음 · 작성 Fatih Kadir Akın — CC0(저작권 포기)로 공개된 원문을 그대로 싣습니다. 한국어 정리 · 실행 결과는 아직 없습니다.