Claude
Skills
Sign in
Back

category-allocation-best-response

Included with Lifetime
$97 forever

Computes the best-response allocation of roster resources across categories in a Head-to-Head Categories matchup. Given our per-category capacity, the opponent's projected output, per-category win probabilities (from matchup-win-probability-sim), and a K-of-N winning threshold, classifies categories into pushed / contested / conceded buckets, emits per-category leverage weights for downstream lineup and streaming decisions, computes the resulting K-of-N win probability, and writes a plain-English rationale. Domain-neutral — portable to any fantasy sport with H2H Cats scoring (MLB 10-cat, NBA 9-cat, NHL 10-cat). Use when you need push/punt decisions, dominated-strategy elimination, leverage weights per cat, or best-response allocation; or when the user mentions "category allocation", "push or punt", "K of N cats", "dominated strategy elimination", "best response allocation", "Blotto fantasy", "leverage weights per cat", or "which cats to push".

General

What this skill does

# Category Allocation Best-Response

## Table of Contents
- [Example](#example)
- [Workflow](#workflow)
- [Common Patterns](#common-patterns)
- [Guardrails](#guardrails)
- [Quick Reference](#quick-reference)

## Example

**Scenario**: Yahoo MLB 10-category H2H, Week 8. Threshold = 6 of 10. Upstream `matchup-win-probability-sim` returned `per_cat_win_probability` for the current week. Our resources: 5 open roster slots, $80 FAAB, 3 streamer starts.

**Inputs**:

| Cat | our_capacity | opp_projection | per_cat_win_prob | Inverse? |
|-----|--------------|----------------|------------------|----------|
| R | 42 | 38 | 0.64 | no |
| HR | 12 | 14 | 0.35 | no |
| RBI | 40 | 41 | 0.47 | no |
| SB | 6 | 4 | 0.72 | no |
| OBP | 0.335 | 0.328 | 0.64 | no |
| K | 55 | 50 | 0.64 | no |
| ERA | 3.85 | 4.10 | 0.65 | yes |
| WHIP | 1.22 | 1.28 | 0.68 | yes |
| QS | 4 | 3 | 0.69 | no |
| SV | 2 | 5 | 0.08 | no |

**Classification by win probability**:

- SV (0.08): `conceded` — dominated strategy. Opponent has 5 projected SV to our 2; no marginal roster slot flips this. Leverage = 0.
- HR (0.35): `contested` — borderline-losing but within reach. Leverage = 1.5.
- RBI (0.47): `contested` — coin-flip. Leverage = 1.5.
- R (0.64), OBP (0.64), K (0.64), ERA (0.65), WHIP (0.68), QS (0.69): `pushed` (lock-in needs attention, 0.25–0.85). Leverage = 1.2. (0.70 is the boundary — one of these would sit on the `contested` side at 1.5 if very close to the line.)
- SB (0.72): `pushed`. Leverage = 1.2.

No cat exceeds 0.85 on this week; no cats are `locked`.

**Outputs**:

- `pushed_cats`: `[SB, QS, WHIP, ERA, K, R, OBP]` (7 cats at 0.64–0.72, ordered by win prob descending)
- `conceded_cats`: `[SV]`
- `contested_cats`: `[HR, RBI]`
- `leverage_weights`: `{R: 1.2, HR: 1.5, RBI: 1.5, SB: 1.2, OBP: 1.2, K: 1.2, ERA: 1.2, WHIP: 1.2, QS: 1.2, SV: 0.0}`
- `k_of_n_win_probability`: **0.605** (Poisson-binomial over the 10 per-cat probabilities with threshold 6)
- `rationale`: *"SV is a dominated strategy (8% flip probability) — do not spend a reliever slot. The 7 pushed cats cover the 6-cat threshold on median, so lock them in and invest marginal resources into HR and RBI (contested, 1.5x leverage) where one extra power bat can flip the matchup."*

Interpretation: if we simply defend the 7 pushed cats we hit threshold in expectation. The contested cats (HR, RBI) are where the highest-leverage moves live — every marginal HR or RBI unit maps almost 1-for-1 to matchup win probability.

## Workflow

Copy this checklist and track progress:

```
Category Allocation Best-Response Progress:
- [ ] Step 1: Validate inputs and confirm upstream signals
- [ ] Step 2: Classify each cat by per_cat_win_probability
- [ ] Step 3: Assign leverage_weights
- [ ] Step 4: Check threshold satisfaction (pushed + contested >= K?)
- [ ] Step 5: Apply borderline-upgrade logic if threshold not met
- [ ] Step 6: Compute k_of_n_win_probability via Poisson-binomial
- [ ] Step 7: Write rationale and emit outputs
```

**Step 1: Validate inputs and confirm upstream signals**

`per_cat_win_probability` is the critical upstream dependency and must come from `matchup-win-probability-sim` (or an equivalent simulator). Do not invent per-cat probabilities from raw capacity vs projection — `matchup-win-probability-sim` accounts for variance, and variance is what determines flip probability for contested cats. See [resources/methodology.md](resources/methodology.md#upstream-dependency-on-matchup-win-probability-sim).

- [ ] Every cat appears in `our_per_cat_capacity`, `opp_per_cat_projection`, and `per_cat_win_probability`
- [ ] All `per_cat_win_probability` values are in `[0, 1]`
- [ ] `cat_win_threshold` is in `[1, N]` where `N = len(cats)`
- [ ] `inverse_cats` is a subset of the cat list
- [ ] `resources_available` dict is present (even if empty — downstream skills may still consume leverage weights without a resource plan)
- [ ] Upstream `random_seed` from `matchup-win-probability-sim` is recorded for audit

**Step 2: Classify each cat by per_cat_win_probability**

Apply the four-tier classification in [Quick Reference](#quick-reference). The thresholds are deliberate — see [resources/methodology.md](resources/methodology.md#why-these-thresholds) for the Blotto-derived rationale.

- [ ] `< 0.25` → `conceded_cats` (dominated strategy — any roster slot here is strictly worse than redeploying)
- [ ] `0.25–0.70` → `contested_cats` (highest marginal value of one more unit)
- [ ] `0.70–0.85` → `pushed_cats` (needs attention but should hold)
- [ ] `> 0.85` → `locked` (do not waste marginal resources — returns are near-zero)
- [ ] Inverse cats (ERA, WHIP, TO, GAA, etc.) use `per_cat_win_probability` directly — the inverse handling has already been applied upstream by `matchup-win-probability-sim`. Do not re-invert.

**Step 3: Assign leverage_weights**

Leverage weights propagate to `mlb-lineup-optimizer`, `mlb-streaming-strategist`, `mlb-waiver-analyst`, and any downstream consumer that maximizes `Σ daily_quality × leverage[cat]`. See [resources/methodology.md](resources/methodology.md#leverage-weight-derivation).

- [ ] `leverage = 0.0` for `conceded_cats` (hard zero — not low, zero)
- [ ] `leverage = 1.5` for `contested_cats` (high marginal value of one more unit)
- [ ] `leverage = 1.2` for `pushed_cats` (above default but below contested)
- [ ] `leverage = 1.0` for `locked` cats (default — marginal gains are redundant)

**Step 4: Threshold satisfaction check**

Verify `len(pushed_cats) + len(contested_cats) >= cat_win_threshold`. If not, we are mathematically unable to reach the win threshold even if we go 100% on our defensible cats; the matchup is presumptively losing and we must either upgrade a borderline-conceded cat or pivot to variance-seeking play. See principle #6 in `frameworks/game-theory-principles.md`.

- [ ] Count `pushed_cats + contested_cats` (these are the cats where we have nonzero flip probability)
- [ ] If count `>= cat_win_threshold`: threshold satisfied, proceed to Step 6
- [ ] If count `< cat_win_threshold`: apply Step 5 borderline-upgrade logic
- [ ] If still insufficient after Step 5: flag the matchup for `variance-strategy-selector` as a high-variance play candidate

**Step 5: Borderline-upgrade logic (conditional)**

If Step 4 fails, look for `conceded_cats` with `per_cat_win_probability` in the `[0.20, 0.25)` "upgrade band". These are just below the concede line — a moderate resource investment (one waiver add, one FAAB bid, one streamer start) can lift them over 0.25 and into the `contested` tier.

- [ ] Sort `conceded_cats` by `per_cat_win_probability` descending
- [ ] Pick the top candidate(s) with `per_cat_win_probability >= 0.20`
- [ ] Reclassify to `contested` and set `leverage = 1.5`
- [ ] Document the upgrade in the rationale with the specific resource cost (e.g., "upgrading HR from conceded: spend 1 roster slot + $15 FAAB on a power bat")
- [ ] Re-run Step 4 — if still short, this matchup is presumptively losing; set a flag and defer to the variance-strategy-selector skill

**Step 6: Compute k_of_n_win_probability via Poisson-binomial**

Treat per-cat wins as independent Bernoullis (the same approximation used by `matchup-win-probability-sim` in `poisson_binomial` mode). Compute `P(sum >= cat_win_threshold)` via the standard PB recurrence. See [resources/methodology.md](resources/methodology.md#poisson-binomial-recurrence).

```
P_0(0) = 1
P_i(k) = P_{i-1}(k) * (1 - p_i) + P_{i-1}(k-1) * p_i   for i = 1..N, k = 0..N
k_of_n_win_probability = sum over k >= threshold of P_N(k)
```

- [ ] Use the post-upgrade `per_cat_win_probability` vector (Step 5 may have modified one entry)
- [ ] Return the overall `k_of_n_win_probability`
- [ ] If the value diverges from the `matchup_win_probability` returned by `matchup-win-probability-sim` by more than 0.03, investigate — the two should match within PB approximation error

**Step 7: Write rationale and emit outputs**

Rationale is a 2–4 sentence plain-Englis

Related in General