mcpField
M
mlb-faab-sizer

mlb-faab-sizer

github.com/lyndonklOther18743 installsUpdated 9w ago
Repository

About mlb-faab-sizer

mlb-faab-sizer is a skill for sizing FAAB bids in MLB fantasy baseball. It combines player value, roster fit, role certainty, and season timing, while delegating auction-specific adjustments to sibling skills and applying baseball-specific guardrails.

Key features

  1. 01Computes baseball-adjusted base value
  2. 02Classifies common and private value
  3. 03Delegates auction valuation and bid shading
  4. 04Estimates bidder counts from opponent profiles
  5. 05Applies budget and role guardrails
  6. 06Outputs recommended bids and rationale

Use cases

  1. 01Sizing a bid for a newly promoted prospect
  2. 02Evaluating bids after a closer change
  3. 03Adjusting player value for roster needs

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/lyndonkl/claude --skill mlb-faab-sizer

After installing, type/mlb-faab-sizerin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

resources/
methodology.md
template.md
resources/evaluators/
rubric_mlb_faab_sizer.json

Details

From the project README

MLB FAAB Sizer

Table of Contents

Delegation Chain

This skill is a baseball-specific orchestrator. It does NOT compute auction math inline. It composes two domain-neutral sibling skills:

StepWhoResponsibility
1this skillCompute base_value from Yahoo-adjusted projection, pos fit, role certainty, urgency, season pace (with league-inflation calibration)
2this skillClassify target as common_value / private_value / mixed
3auction-winners-curse-haircutReturn adjusted_valuation (Bayesian haircut for common-value)
4this skillEstimate N from opponent profiles
5auction-first-price-shadingReturn shaded_bid ((N-1)/N + distribution + risk adjustment)
6this skillApply baseball guardrails (April 40%, speculation 20%, $1 floor, role-cert floor)
7this skillEmit faab_rec_bid, faab_max_bid, rationale naming both delegations

Invariant: this skill never computes (N-1)/N or a common-value haircut directly. Any change to those primitives is made in the sibling skills.

Example

Scenario: Roki Sasaki called up, likely Dodgers rotation spot. $100 FAAB remaining, week 4.

  1. base_value (this skill): 28 x 0.70 x 0.65 x 1.2 x 0.7 = $10.70
  2. Classify: common_value (headline prospect).
  3. Invoke auction-winners-curse-haircut with (raw=10.70, type=common_value, N=6, dispersion=60) -> adjusted_valuation = $7.39, haircut 31%.
  4. N estimate: 6 opponents have SP need + budget.
  5. Invoke auction-first-price-shading with (true_value=7.39, N=6, dist=log-normal, risk=0.2, budget=100) -> shaded_bid = $7, shade 0.90.
  6. Baseball guardrails: all clear.
  7. Output: faab_rec_bid=$7, faab_max_bid=round($7.39 x 0.90)=$7. Rationale cites both sibling skills.

Full trace in resources/methodology.md and resources/template.md.

Workflow

FAAB Sizing Progress:
- [ ] Step 1: Collect input signals and budget state
- [ ] Step 2: Compute base_value (baseball layering)
- [ ] Step 3: Classify value_type
- [ ] Step 4: Invoke auction-winners-curse-haircut -> adjusted_valuation
- [ ] Step 5: Estimate N from opponent profiles
- [ ] Step 6: Invoke auction-first-price-shading -> shaded_bid
- [ ] Step 7: Apply baseball guardrails
- [ ] Step 8: Emit signal + rationale with delegation trace

Step 1: Collect inputs (ask caller if missing):

  • acquisition_value ($, 1-100 scale) -- from mlb-player-analyzer
  • positional_need_fit (0-100) -- from mlb-waiver-analyst
  • role_certainty (0-100) -- from mlb-player-analyzer
  • FAAB remaining, week number, situation label

Step 2: Compute base_value (baseball-specific layering):

base_value = acquisition_value
           x (positional_need_fit / 100)
           x (role_certainty / 100)
           x urgency_multiplier          [0.7 - 1.4]
           x season_pace_multiplier      [0.6 - 1.4 after inflation calib]

Urgency: 1.4 (closer loses job / prospect called up); 1.2 (new opportunity); 1.0 (steady); 0.8 (wave); 0.7 (speculation).

Pace base: 0.6 (Apr wk 1-4), 1.0 (May-Jun), 1.2 (Jul-Aug), 1.4/0.5 (Sept contending/eliminated). Then multiply by league_inflation_ratio from tracker/faab-log.md (see methodology.md). Min 5 valid rows; else skip calibration and flag low_calibration_data.

Step 3: Classify value_type:

  • common_value: headline prospect, named closer, star off IL (same info for all teams)
  • private_value: handcuff, platoon fit, punt-category-specific (only we weigh this way)
  • mixed: record common/private weight

Default to common_value when uncertain (conservative; triggers haircut).

Step 4: Invoke auction-winners-curse-haircut — keyed off CONTESTED bidders, not the full field:

inputs = { raw_valuation: base_value, value_type, n_informed_bidders: n_contesters,
           signal_dispersion: 40 (default) }

n_contesters = rivals realistically expected to bid on THIS specific target (see Step 5). Do NOT pass the full plausible field here. The winner's-curse haircut (Step 4) and the first-price shade (Step 6) MUST key off different counts — otherwise one "many bidders" signal is counted twice and we systematically under-bid contested closers/call-ups to ~58% of true value (audit 2026-06-02, the verified mlb-faab-sizer double-count). If n_contesters <= 1 the target is effectively uncontested → the haircut short-circuits to 0 (treat as private-value). Consume adjusted_valuation; preserve classification_rationale. Dispersion defaults: 60 prospects, 30 established, 40 otherwise.

Step 5: Estimate the TWO bidder counts from opponent profiles (they are deliberately different numbers; they converge only when a target is genuinely hotly contested):

  • n_contesters (drives Step 4 haircut) — rivals with positional_need > 50 AND faab > 20% original AND activity >= moderate AND a concrete reason to want THIS player. In our deflated market (modal winning bid $1-2) this is typically 1-2, occasionally 3-4 for a confirmed closer change. Clamp [0, 6].
  • N_field (drives Step 6 shading) — the broader set who could plausibly bid. Clamp [1, 8]. Defaults: common superstar 6, role-player 3, private 1-2.

Step 6: Invoke auction-first-price-shading — keyed off the full field:

inputs = { true_value: adjusted_valuation, n_bidders_estimate: N_field,
           value_distribution: "log-normal" (MLB default),
           risk_aversion: 0.2 (bump to 0.4 for contending September),
           budget_remaining: faab_remaining }

shaded_bid becomes pre-guardrail faab_rec_bid. Set faab_max_bid = round(adjusted_valuation x 0.90).

Step 7: Apply baseball guardrails (see below). Never silently violate.

Step 8: Emit via mlb-signal-emitter. User-facing rationale MUST name both sibling skills by purpose. Validate with rubric. Minimum 3.5.

Common Patterns

1. Hot common-value call-up (early season): N=5-7, pace 0.6-0.7, haircut ~25-30%, shade ~0.80-0.85. Typical $5-$12 rec.

2. Private-value handcuff: N=1-2, haircut=0 (short-circuit), shade 0.0-0.5. Typical $1-$3 rec.

3. Closer change (mid-season, common-value): N=5-8, urgency 1.4, haircut ~25%, shade ~0.83. Typical $10-$30 rec.

4. September contender stretch target: pace 1.4, risk_aversion bumped to 0.4, shade ~0.88-0.92. Can reach 40-60% of remaining FAAB.

Guardrails

  1. April 40% cap: weeks 1-13, faab_max_bid ≤ 40% of FAAB remaining. Flag april_40pct_cap_triggered.
  2. Speculation 20% cap: if situation=speculation or role_certainty<30, cap at 20%. Flag speculation_20pct_cap_triggered.
  3. $1 floor: if shaded_bid rounds to $0 but positional_need_fit >= 30, bid $1 (rolling-list tiebreak). Otherwise bid $0 and flag zero_bid_preservation.
  4. Role certainty floor: if role_certainty < 20, force faab_rec_bid = $0. Flag role_certainty_floor.
  5. Regression override: if regression_index < -30, cut faab_rec_bid by 30%. Flag regression_luck_discount.
  6. Variant divergence: advocate/critic differ >30% -> take critic. Flag variant_divergence_applied.
  7. Budget floor (post-July): if week >= 14 and remainder < $5, flag budget_floor_near_zero.
  8. Log the decision: every computation via mlb-decision-logger (including $0 bids).

Do NOT duplicate sibling caps: the 0.9 x true_value ceiling is enforced by auction-first-price-shading; the 35% haircut cap is enforced by auction-winners-curse-haircut. Trust them.

Quick Reference

Pipeline:

base_value = acq_value x (pos_fit/100) x (role_cert/100) x urgency x pace_calibrated

adjusted_valuation = auction-winners-curse-haircut(
    raw_valuation=base_value, value_type, n_informed_bidders=N, signal_dispersion)

shaded_bid = auction-first-price-shading(
    true_value=adjusted_valuation, n_bidders_estimate=N,
    value_distribution="log-normal", risk_aversion=0.2, budget_remaining)

faab_rec_bid = round(shaded_bid)          # then baseball guardrails
faab_max_bid = round(adjusted_valuation x 0.90)

Inputs required: acquisition_value, positional_need_fit, role_certainty, FAAB remaining, week, situation label, regression_index (optional).

Outputs: faab_rec_bid, faab_max_bid, value_type, N, adjusted_valuation, shaded_bid, multipliers, guardrail flags, user-facing rationale.

Sibling skills:

  • @skills/auction-first-price-shading/ -- (N-1)/N + distribution + risk-aversion
  • @skills/auction-winners-curse-haircut/ -- Bayesian common-value haircut

Key resources:

Comments

Markdown supported