From thinking-frameworks-skills
Computes a single player's expected FIFA World Cup Fantasy points per round (xEV) by combining start probability, minute-based scoring tiers, fixture-scaled npxG/xA, defensive floors, set-piece premium, and downside risks.
How this skill is triggered — by the user, by Claude, or both
Slash command
/thinking-frameworks-skills:wc-player-evThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Implements the `xEV(player)` formula defined in `footballfantasy/context/frameworks/scoring-rules.md`. Everything in this system that talks about a player's value — a strategist weighting a pick, the captain ladder sampling a candidate's distribution, `wc-fitness-eval` summing `raw_xEV` — ultimately samples the number this skill produces. So it has one job and must do it precisely: turn a **sco...
Implements the xEV(player) formula defined in footballfantasy/context/frameworks/scoring-rules.md. Everything in this system that talks about a player's value — a strategist weighting a pick, the captain ladder sampling a candidate's distribution, wc-fitness-eval summing raw_xEV — ultimately samples the number this skill produces. So it has one job and must do it precisely: turn a scout signal (minutes model, npxG/xA, set-piece duty, card/rotation/injury risk) plus the round's fixture and clean-sheet signals into a player's expected points for this round, with the decomposition exposed so downstream agents reason about why, not just how much.
Two properties dominate every other term and must never be smoothed over:
This skill is the floor-and-ceiling factory. It does not decide captaincy (that sequencing belongs to wc-captain-ladder, which samples the per-player distribution this skill emits), does not score rank-relative fitness (that belongs to wc-fitness-eval), and does not derive its own clean-sheet probability or fixture difficulty (those are upstream signals — read them, never recompute).
wc-scout chains into it to attach an EV to a player it has just profiled.wc-strategist genotype calls it per candidate player and then re-weights the output by genotype (A2 multiplies appeal by low-ownership leverage; A5 maximises the floor term; A4 leans on the fixture-scaled attacking terms against a weak opponent). The skill returns a neutral xEV; the archetype tilt happens in the caller.wc-matchday-tactician calls it for XI/bench ordering and to feed the captain ladder the distributions it sequences.wc-fitness-eval consumes the emitted player-ev signals as raw_xEV inputs — it must read them, not re-derive.- [ ] 1. Read the scout signal for this player+round (start_prob, p60, npxg90, xa90, setpiece_share, pen_taker, rotation_risk, injury, suspension, minutes_model). DO NOT re-scout.
- [ ] 2. Read the round fixture signal (opponent strength / mismatch) and the clean-sheet signal (p_cs, expected_ga for the player's team). DO NOT recompute them.
- [ ] 3. Confirm scoring-rules.md point values: is `confirmed: true`? If not, set a provisional flag — relative ordering holds, absolute magnitudes carry a calibration caveat.
- [ ] 4. Resolve the minutes projection: expected_minutes from minutes_model; derive minutes_factor (= proj_min / 90) and the two appearance probabilities (P(plays), P(plays60+)).
- [ ] 5. Scale attacking output: xG_adj = npxg90 × minutes_factor × fixture_mult; xA_adj = xa90 × minutes_factor × fixture_mult. Add the penalty/set-piece premium into xG_adj/xA_adj where the scout confirms the duty.
- [ ] 6. Compute each EV term with the position-specific lambdas (goal weights GK10/DEF6/MID5/FWD4; cs weights GK4/DEF4/MID1/FWD0; etc.).
- [ ] 7. Sum to xEV. Build the decomposition (one line per term, signed).
- [ ] 8. Estimate variance, ceiling (P90-ish best realistic line), floor (P10-ish — usually the no-60'/blank line).
- [ ] 9. Set confidence: cap at 0.35 if minutes are unconfirmed or any load-bearing fact is web-unconfirmed; cap provisional if step 3 failed.
- [ ] 10. Emit the `player-ev` signal via wc-signal-emitter. Return its path.
xEV(player) = P(plays) · appearance_tier_EV # the 1–59' floor
+ P(plays 60+) · minutes_bonus # the 60' cliff (step, not ramp)
+ λ_goal(pos) · xG_adj # fixture- & minutes-scaled npxG (+ pen/SP premium)
+ λ_assist · xA_adj # fixture- & minutes-scaled xA (+ SP-creation premium)
+ λ_cs(pos) · P(clean sheet | fixture) # GK/DEF/MID only — needs 60'
+ λ_save · expected_saves # GK only
+ λ_defact · P(def-actions threshold) # DEF / ball-winning MID
+ λ_setpiece · set_piece_share # residual premium not already in xG_adj/xA_adj
− λ_card · card_risk # yellow/red expectation
− λ_concede(pos) · expected_GA # GK/DEF — the −1 per 2 conceded bracket
All point magnitudes (appearance_tier_EV, minutes_bonus, the λs) are read from scoring-rules.md. The skill never hard-codes them in a way that survives a rules update — if that file says confirmed: false, every absolute number below is provisional.
| λ | GK | DEF | MID | FWD | note |
|---|---|---|---|---|---|
appearance_tier_EV (1–59') | +1 | +1 | +1 | +1 | floor of any pick that gets on the pitch |
minutes_bonus (the 60' tier, total when 60+) | +2 | +2 | +2 | +2 | the cliff — modelled as the extra above the 1–59' tier |
λ_goal | 10 | 6 | 5 | 4 | a DEF goal pays more but fires far less often |
λ_assist | 3 | 3 | 3 | 3 | position-flat |
λ_cs (clean sheet, 60+) | 4 | 4 | 1 | 0 | the defensive-stack engine; MID gets a token, FWD nothing |
λ_save (per 3 saves) | ~0.33/save | — | — | — | GK only; expected_saves × (1/3) |
λ_defact (def-actions threshold) | — | +2 | +2 | — | CB/full-back clearances-blocks-interceptions or tackles; the hidden floor |
λ_concede (per 2 conceded) | −0.5/goal | −0.5/goal | — | — | GK/DEF only; expected_GA × (1/2) |
λ_card | −1 yellow / −3 red | same | same | same | position-flat |
The asymmetry the manager already knows but the math must honour: a defender's goal is worth 6 to a forward's 4, but a centre-back's per-match npxG is a fraction of a striker's, so on raw goal EV forwards still win — except a set-piece-threat CB against a weak, set-piece-vulnerable opponent, whose xG_adj can spike enough that 6 × xG_adj rivals a forward's 4 × xG_adj. That crossover is exactly what this skill exists to surface; do not pre-judge it, compute it.
1. Minutes resolution (do this first — it gates everything).
From the scout's minutes_model derive an expected_minutes projection. Then:
minutes_factor = expected_minutes / 90 (a 70-minute projection ⇒ ~0.78; this scales all open-play output linearly — a player on the pitch 78% of the match generates ~78% of a 90-minute xG/xA baseline).P(plays) = start_prob + (cameo probability if a likely sub). Use the scout's start_prob/p60 directly; do not invent them.P(plays 60+) = p60 from the scout. This is the gate on the appearance bonus and on every clean-sheet/defensive return (those require the 60' threshold).The cliff in practice: a nailed starter with p60 ≈ 0.92 banks the bonus tier almost every week; a 65%-to-start rotation risk with p60 ≈ 0.5 loses roughly half the appearance bonus and half the clean-sheet EV and widens variance — model it as the probability-weighted step, never as "minutes × a rate."
2. Fixture & minutes scaling of attacking output.
fixture_mult = opponent-adjusted multiplier from wc-fixture-progression's `fixture` signal
(a striker vs a leaky minnow > 1; vs an elite, deep-block defence < 1)
xG_adj = npxg90 · minutes_factor · fixture_mult
xA_adj = xa90 · minutes_factor · fixture_mult
npxg90/xa90 are non-penalty per-90 rates from the scout (npxG strips penalties so they aren't double-counted). fixture_mult is read, not derived — wc-fixture-progression already encodes opponent defensive/attacking strength for this specific fixture, and the team's clean-sheet probability comes from wc-clean-sheet-model. Typical band: ~0.6 (brutal matchup) to ~1.5 (mismatch); the fixture signal supplies the exact value.
3. The penalty / set-piece premium (fold in here, then avoid double-count).
If the scout flags pen_taker: true, add the expected penalty contribution into xG_adj:
xG_adj += P(team wins a penalty this match) · P(this player takes it) · P(scores | takes)
A primary penalty taker on a side that draws ~0.25–0.4 penalties/match is carrying meaningful extra goal expectation that open-play npxG misses entirely — this is the premium, and it is why pen-takers are a top-3 scout focus. For primary set-piece delivery (corners, direct free-kicks), add the incremental created-chance expectation into xA_adj. Whatever portion of set-piece value you have already folded into xG_adj/xA_adj here must NOT be re-added by the standalone λ_setpiece · set_piece_share term — that residual term covers only set-piece duty value not already expressed as xG/xA (e.g. a "won penalty" the player draws but doesn't take). Keep the books clean: premium counted once.
4. Clean-sheet term (GK/DEF, token MID).
+ λ_cs(pos) · P(clean sheet | fixture, team)
P(clean sheet) is read straight from the clean-sheet signal (wc-clean-sheet-model) for the player's team in this fixture — never recompute it here. Note it is implicitly conditioned on the player surviving to 60'; if p60 is low, the realised clean-sheet EV is P(cs) · (p60 / typical_starter_p60) — a rotation-risk defender cannot bank a clean sheet he's subbed out of. FWD: this term is zero. MID: token (×1), but it still tips marginal mid choices toward the strong-defence side.
5. Saves (GK only).
+ λ_save · expected_saves where expected_saves ≈ opponent_shots_on_target_estimate (from fixture signal),
scored at (1/3) point per save.
A shot-stopper behind a mid-tier defence facing a strong attack can paradoxically out-save-EV a keeper behind a dominant side who faces three shots — the save points and the clean-sheet points pull in opposite directions, and this skill exposes both so the caller sees the trade.
6. Defensive-actions threshold (DEF / ball-winning MID — the hidden floor).
+ λ_defact · P(player hits the CBI/tackles threshold this match)
From the scout's per-90 defensive-action rate and the fixture (a defender vs a side that attacks a lot sees more clearance/interception volume → higher threshold-hit probability). This is the term that gives a busy attacking full-back or a destroyer-mid a floor independent of clean sheets, and it is why such players are not pure clean-sheet lottery tickets.
7. Negative terms.
− λ_card · card_risk (E[yellow] · 1 + E[red] · 3 ; a booking-prone player or a derby/high-stakes ref tilts this up;
watch yellow-card accumulation before knockouts — a suspension-risk yellow has cost beyond the −1)
− λ_concede(pos) · expected_GA (GK/DEF only; expected_GA from the clean-sheet signal, scored at −0.5/goal i.e. −1 per 2 conceded)
expected_GA is the same upstream clean-sheet signal's field — read it. A leaky defence's downside enters here; it is what makes a cheap defender on a bad side a negative-tail pick even when his clean-sheet term is non-zero.
A set-piece centre-back, nailed starter (p60 ≈ 0.9), npxg90 = 0.12, on a tournament favourite vs a weak set-piece-vulnerable minnow (fixture_mult ≈ 1.4, P(cs) ≈ 0.55, expected_GA ≈ 0.7), not a pen-taker, hits the defensive-actions threshold ~60% of matches:
appearance ≈ 0.95 · 1 + 0.90 · 2(extra→ here total 2) ≈ ~2.8 (floor: he plays and clears 60')
goal 6 · xG_adj = 6 · (0.12 · 1.0 · 1.4) ≈ 6 · 0.168 ≈ 1.0
assist 3 · xA_adj ≈ small ≈ 0.2
clean 4 · 0.55 ≈ 2.2
defact 2 · 0.60 ≈ 1.2
concede −0.5 · 0.7 ≈ −0.35
card −1 · ~0.15 ≈ −0.15
xEV ≈ 7.1 ceiling ≈ 16 (header + CS), floor ≈ 1 (no 60' / conceded 2+)
The point is mechanical, not the exact total: against the right opponent the λ_goal=6 weight plus a real CS probability lifts a set-piece CB into captain-ladder-adjacent territory — and the decomposition shows the manager it's a set-piece-and-stack bet, not form.
variance_band: low|medium|high.wc-fitness-eval leans on when θ=protect.The ceiling/floor split is the whole reason this skill emits a distribution and not a point estimate: A5 (EV Maximizer) reads the floor, A2 (Differential Hunter) reads the ceiling, the captain ladder reads both.
player-ev signal)Emit via wc-signal-emitter to signals/<round>-player-ev-<player>.md:
---
type: player-ev
round: <round id, e.g. 2026-grp-md2>
date: <YYYY-MM-DD>
emitted_by: wc-player-ev
confidence: <0.00–1.00> # ≤0.35 if minutes unconfirmed or a load-bearing fact web-unconfirmed
source_urls:
- <scout signal path or url> # facts trace to the scout signal / fixture / clean-sheet signals, or manager-provided
provisional_scoring: <true|false> # true if scoring-rules.md is not confirmed:true → absolute magnitudes caveated
---
player: <name>
team: <nation>
position: <GK|DEF|MID|FWD>
price: <m>
fixture: <opponent + home/away>
minutes:
expected_minutes: <n>
minutes_factor: <proj_min/90>
start_prob: <0–1> # from scout — not re-derived
p60: <0–1> # from scout — the cliff gate
xEV: <number> # the headline
decomposition: # signed, sums to xEV — MANDATORY (the board/fitness explain through it)
appearance: <n>
minutes_60_bonus: <n>
goal: <n> # λ_goal(pos) · xG_adj
assist: <n> # λ_assist · xA_adj
clean_sheet: <n> # λ_cs(pos) · P(cs) (0 for FWD)
saves: <n> # GK only
def_actions: <n> # DEF/ball-winning MID
set_piece_residual: <n> # premium NOT already folded into goal/assist
card: <-n>
concede: <-n> # GK/DEF only
scaled_inputs:
xG_adj: <n> # npxg90 · minutes_factor · fixture_mult (+ pen premium if taker)
xA_adj: <n>
fixture_mult: <n>
pen_taker: <true|false>
pen_premium_in_xG: <n> # portion of xG_adj from penalties (0 if not taker)
variance: <n>
variance_band: low|medium|high
ceiling: <n> # ~P90 realistic best line
floor: <n> # ~P10 — usually the no-60'/blank line
flags:
- <e.g. "penalty taker — top-3 EV premium">
- <e.g. "rotation risk: p60 0.5, re-check XI ~24h pre-lock">
- <e.g. "yellow-card accumulation: one booking from a knockout suspension">
recheck_before_lock: <true|false> # true whenever minutes are projected, not confirmed
---
start_prob, p60, npxg90, xa90, setpiece_share, pen_taker, rotation_risk, injury, suspension all come from the scout signal. If it is missing for this player+round, return that the scout must run first — do not fabricate minutes or rates.P(clean sheet), expected_GA, and fixture_mult are read from wc-clean-sheet-model and wc-fixture-progression. Re-deriving them here would desync the system and double-handle uncertainty.scoring-rules.md is confirmed: true before trusting absolute magnitudes. If it is not, set provisional_scoring: true and caveat the xEV — relative ordering between players is still usable, exact point totals are not.injury/suspension unresolved) or any other load-bearing fact could not be web-confirmed, and set recheck_before_lock: true. Minutes are the dominant lever — an unconfirmed start makes the whole distribution speculative.minutes/90 × bonus. It is gated on p60. Clean-sheet and defensive returns are gated on the same threshold.xG_adj/xA_adj must not also appear in the set_piece_residual term. Report pen_premium_in_xG so the caller can see it.wc-fitness-eval's and the strategists' job. This skill emits the raw per-round distribution they sample.wc-captain-ladder handles the across-kickoff doubling. Do not 2× anything here.npx claudepluginhub lyndonkl/claude --plugin thinking-frameworks-skillsScores FIFA World Cup Fantasy squad plans with risk-adjusted, rank-relative fitness, factoring ownership, variance, and rank objective. Useful for evolutionary selection or evaluating candidate squads.
Calculate derived football metrics such as xG, xGOT, PPDA, expected threat, and passing networks from raw event data. Useful for football analytics and model building.
Builds a tactical game plan by analyzing opponent weaknesses, team strengths, and match context using performance indicators and decision rules.