From thinking-frameworks-skills
Analyzes single MLB game matchup from fantasy baseball view given home/away teams and date. Outputs normalized signals (opp_sp_quality, park_hitter_factor, park_pitcher_factor, weather_risk, bullpen_state) plus platoon narrative for start/sit and streaming decisions.
npx claudepluginhub lyndonkl/claude --plugin thinking-frameworks-skillsThis skill uses the workspace's default tool permissions.
- [Example](#example)
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Scenario: User needs to decide whether to start Junior Caminero (TB, RHB) for today's game. Game: Tampa Bay Rays @ Colorado Rockies, 2026-04-17, Coors Field.
Research pass (web search, cite every URL):
Normalization pass:
opp_sp_quality (COL SP viewed from TB hitters' side): Marquez is below-average -> low hitter-opposition. Score = 30 (50 = league-average starter; lower = easier matchup for hitters).park_hitter_factor: Coors wOBAcon 1.18 -> normalize so 1.00 = 50. Score = 74 (very hitter-friendly).park_pitcher_factor: inverse of above. Score = 26 (very unfriendly to pitchers).weather_risk: 0% precip + mild temp + supportive wind -> 8 (very low disruption risk).bullpen_state (for the home team, COL): closer rested, setup healthy -> 65. (For TB: closer gassed -> 35.)Platoon narrative (plain English, no jargon): "Caminero hits right-handed and faces a right-handed pitcher. This is a neutral handedness matchup, not a platoon advantage. However, Caminero's hard-hit rate vs RHP is above his season average, and Coors Field is the best hitter park in baseball, so the overall matchup is strongly positive."
Composed downstream: mlb-player-analyzer reads these signals and produces matchup_score = 40% opp_sp + 25% park_hitter + 25% platoon + 10% weather -> ~72 for Caminero today. That feeds daily_quality -> START.
Copy this checklist and track progress:
MLB Matchup Analysis Progress:
- [ ] Step 1: Collect game identifiers (home, away, date, first pitch time)
- [ ] Step 2: Identify both probable starting pitchers + handedness
- [ ] Step 3: Pull park factors (home park)
- [ ] Step 4: Pull weather forecast for first-pitch window
- [ ] Step 5: Assess bullpen state for both teams
- [ ] Step 6: Normalize each signal to 0-100 (50 = neutral)
- [ ] Step 7: Write platoon narrative (plain English)
- [ ] Step 8: Emit signal file and validate
Step 1: Collect game identifiers
Step 2: Identify probable starters
Pull from MLB.com probable pitchers (https://www.mlb.com/probable-pitchers). See resources/methodology.md for search procedure and fallbacks.
Step 3: Pull park factors
Use FanGraphs 2026 park factors (guts.aspx?type=pf). See resources/methodology.md for the normalization formula (raw factor -> 0-100 scale).
Step 4: Pull weather forecast
Use RotoWire weather (rotowire.com/baseball/weather-forecast.php). See resources/methodology.md for the risk formula.
Step 5: Assess bullpen state
Use RotoBaller closer depth chart + last-7-day usage reports. See resources/methodology.md.
Step 6: Normalize signals
Every signal must land on a 0-100 scale where 50 = league-average / neutral. See resources/methodology.md for each signal's formula.
opp_sp_quality computed from each side's perspectivepark_hitter_factor anchored so neutral park = 50park_pitcher_factor = 100 - park_hitter_factor (approximate inverse)weather_risk = rain_prob_pct x importance_multiplier, capped at 100bullpen_state computed per team (home + away)Step 7: Write platoon narrative
Per CLAUDE.md rule 5: jargon-free or translated inline. For each key hitter of interest, state handedness and the SP's handedness, then describe the platoon edge or lack thereof in plain English. See resources/template.md.
Step 8: Emit and validate
Write to signals/YYYY-MM-DD-matchup.md using resources/template.md. Call mlb-signal-emitter for validation. Validate against resources/evaluators/rubric_mlb_matchup_analyzer.json. Minimum standard: average score 3.5+.
| Signal | Range | Meaning |
|---|---|---|
opp_sp_quality | 0-100 | Opposing starter's true-talent + today's matchup. 50 = league-average SP. Higher = tougher matchup for the hitters facing them. |
park_hitter_factor | 0-100 | 50 = neutral. >50 = hitter-friendly (Coors, Cincinnati). <50 = pitcher-friendly (Oracle, T-Mobile). |
park_pitcher_factor | 0-100 | 50 = neutral. >50 = pitcher-friendly. Typically ~= 100 - park_hitter_factor, with small corrections for park-specific effects (foul territory, etc.). |
weather_risk | 0-100 | 0 = dome or perfect conditions. 100 = high postponement + in-game disruption risk. |
bullpen_state | 0-100 | Per team. 50 = normal. >50 = bullpen healthy and rested. <50 = gassed / depleted / IL-depleted. |
Plus a narrative block covering platoon implications for both lineups.
50 is neutral, always. Every signal is anchored so 50 = league-average. If your formula produces a distribution that doesn't hit 50 at the median, it's wrong -- re-anchor.
Cite every URL. Every signal value must be traceable to a specific source URL in source_urls:. If a fact cannot be verified via web search, drop confidence to 0.3 or lower and flag in red team.
Park factors are context-dependent. Handedness splits matter: Yankee Stadium favors LHB; Fenway's Green Monster favors RHB pull-hitters. If a key hitter has extreme splits, use the handedness-specific park factor, not the composite.
Weather = rain probability x importance multiplier. A 30% rain chance matters more in a September pennant race than in April. See methodology for the importance multiplier.
Bullpen state is per team, not per game. Emit two values: bullpen_state_home and bullpen_state_away. Downstream consumers pick the one they need (e.g., the streaming-strategist cares about the opposing bullpen for a late-game lead).
Platoon narrative must be jargon-free. Never write "positive splits vs RHP." Write "hits right-handed pitchers better than left-handed pitchers." Translate every stat the first time it appears.
Dome overrides weather. If the home park is a dome (or the roof is confirmed closed), set weather_risk = 0 regardless of forecast, and note the roof status in the signal body.
Both SPs, both sides. The signal file should report opp_sp_quality from both perspectives: the home team's hitters face the away SP, and vice versa. Do not pick only one.
Key formulas:
park_hitter_factor = 50 + (raw_wOBAcon_factor - 1.00) * 200
(clamped to [0, 100]; neutral park wOBAcon ~ 1.00 -> 50)
park_pitcher_factor = 100 - park_hitter_factor (first-order approximation)
opp_sp_quality = 50 + (lg_avg_xFIP - SP_xFIP) * 15
(better SP = higher score = tougher on opposing hitters)
weather_risk = min(100, rain_prob_pct * importance_multiplier)
importance_multiplier: 1.0 (early season) .. 1.5 (playoff push) .. 2.0 (postseason)
bullpen_state = 50
- 15 if closer unavailable
- 10 per high-leverage arm unavailable
+ 5 if closer had 2+ days rest and full bullpen rested
(clamped [0, 100])
Key sources (see context/frameworks/data-sources.md for the full list):
Inputs required: home team, away team, date (YYYY-MM-DD), first-pitch time (optional).
Outputs produced: one signal file at signals/YYYY-MM-DD-matchup.md with frontmatter + matchup summary table + platoon narrative + source URLs.
Key resources: