Weekly refresh of per-opponent archetype + behavioral profiles for the 11 opposing teams in the user's Yahoo Fantasy Baseball league (ID 23756). Thin baseball-specific wrapper around the domain-neutral `opponent-archetype-classifier` -- provides the 10-archetype MLB taxonomy (balanced, stars_and_scrubs, punt_sv, punt_sb, punt_wins_qs, hitter_heavy, pitcher_heavy, inactive, frustrated_active, unknown), extracts MLB features from Yahoo pages (draft distribution, FAAB spend, waiver pattern, roster composition, lineup consistency, trade activity, recent record, activity recency), invokes the classifier, and writes/updates `context/opponents/<team-slug>.md` files per `opponent-profile-schema.md`. Read-modify-write preserves manual notes. Emits a weekly summary signal at `signals/wkNN-opponent-profiles.md`. Use when user says "opponent profiling", "classify opposing manager", "update opponent profiles", "refresh opponents", "weekly opponent scout", or "MLB fantasy opponent archetype".
Weekly refresh of per-opponent archetype + behavioral profiles for the 11 opposing teams in the user's Yahoo Fantasy Baseball league (ID 23756). Thin baseball-specific wrapper around the domain-neutral `opponent-archetype-classifier` -- provides the 10-archetype MLB taxonomy (balanced, stars_and_scrubs, punt_sv, punt_sb, punt_wins_qs, hitter_heavy, pitcher_heavy, inactive, frustrated_active, unknown), extracts MLB features from Yahoo pages (draft distribution, FAAB spend, waiver pattern, roster composition, lineup consistency, trade activity, recent record, activity recency), invokes the classifier, and writes/updates `context/opponents/<team-slug>.md` files per `opponent-profile-schema.md`. Read-modify-write preserves manual notes. Emits a weekly summary signal at `signals/wkNN-opponent-profiles.md`. Use when user says "opponent profiling", "classify opposing manager", "update opponent profiles", "refresh opponents", "weekly opponent scout", or "MLB fantasy opponent archetype".
Scenario: Monday morning of Week 5. Refresh profile for Springfield Isotopes (manager Nikolay) after observing another high-activity week (7 moves, $14 spent on adds, 4-1 matchup win).
archetype_taxonomy:# see resources/template.md -- 10 archetypesbalanced: {...}
stars_and_scrubs: {...}
...observed_features:<fromstep2>archetype_prior:<prior_profile.posterior># sequential: last week's posterior is this week's priorobservation_weight:0.65# Week 5 -- see methodology.md observation_weight_calibrationcorrelated_feature_pairs:- [moves_per_week, faab_spent_pct] # active managers do both- [sp_roster_share, closer_count] # they trade off
Step 4 -- Classifier returns:
posterior:balanced:0.58# up from 0.42 -- evidence accumulatingstars_and_scrubs:0.12hitter_heavy:0.10frustrated_active:0.08# record is winning, so frustrated_active downpitcher_heavy:0.07punt_sb:0.03punt_sv:0.01punt_wins_qs:0.01inactive:0.00unknown:0.00map_archetype:balancedclassification_confidence:37.7# 0.58 * 0.65 * 100 -- still just under 40best_response_hints:-"Match cat-for-cat; decided on execution"-"Include in N-estimate for every common-value FAAB target"-"Active manager -- probe for fair consolidation trades"
The "Summary", "Apparent weaknesses", "Best response" and "Open questions" sections contain hand-authored user notes -- keep verbatim. Only these get refreshed:
Step 6 -- Emit weekly signal at signals/wk05-opponent-profiles.md:
---
type: opponent_profile_summary
date: 2026-04-20
week: 5
emitted_by: mlb-opponent-profiler
confidence: 0.65
source_urls: [<11 team pages + transactions + teams>]
---
## Archetype shifts since Week 4- Springfield Isotopes: balanced 0.42 -> 0.58 (confidence 0.50 -> 0.66). Nikolay continues active pattern, record confirms execution.
- Jennys Team: inactive 0.78 -> 0.84 (confidence 0.80 -> 0.85). Still zero moves. Profile hardening.
- ...9 more
## New reactivity triggers fired- Team 7 (Kenyi) -- outbid us on Wade Miley at $14; shift `faab_avg_bid_pct` up
Workflow
Copy this checklist and track progress:
Opponent Profiler Progress (per team, x 11 for all_opponents):
- [ ] Step 1: Resolve team identity (team_name -> team_id, manager_alias)
- [ ] Step 2: Scrape 4 Yahoo pages for this team
- [ ] Step 3: Extract MLB-specific features (9 features; see template.md)
- [ ] Step 4: Load prior_profile.posterior as archetype_prior (sequential update)
- [ ] Step 5: Invoke opponent-archetype-classifier with 10-archetype MLB taxonomy
- [ ] Step 6: Compute cat_strength (0-100 per cat) from roster composition
- [ ] Step 7: Read existing context/opponents/<slug>.md; identify manual-notes sections
- [ ] Step 8: Write updated file atomically (preserve manual notes)
- [ ] Step 9: (at end of batch) Emit signals/wkNN-opponent-profiles.md summary
Step 1: Resolve team identity
Input is either a single team_name (case-insensitive, fuzzy match against canonical Yahoo names) or all_opponents: true (iterate over team_ids 1-12, skipping user's own team_id). Map to team_id and team-slug (lowercased, hyphenated).
If team_name does not match any Yahoo team, return error -- do not guess
team-slug must match the filename on disk at context/opponents/<slug>.md (or create new file if absent)
lineup_set_daily (bool -- any benched-but-MLB-starting players in last 7 days?)
trade_offers_sent, trade_offers_received
record_last_2_weeks, days_since_last_login
Step 4: Sequential-update prior
Read prior_profile.posterior (if supplied) and pass as archetype_prior to the classifier. This is the key sequential-Bayes move: last week's posterior becomes this week's prior.
If no prior_profile, use taxonomy priors (Week 1 only)
If prior_profile.posterior sums to != 1.0, normalize and flag in assumptions_flagged
Pass the 10-archetype MLB taxonomy from resources/template.md along with the observed features, prior, and observation_weight. Do not re-implement Bayesian math in this skill. The classifier returns posterior, map_archetype, classification_confidence, best_response_hints, feature_contribution_breakdown, assumptions_flagged.
Pass correlated_feature_pairs (see Guardrails #1)
If classifier returns map_archetype: "inconclusive", write archetype as unknown with confidence as returned
Do not override or reinterpret classifier output -- store it as-is
Step 6: Compute cat_strength (0-100 per cat)
Classifier returns the archetype; the 10 per-cat strength scores come from a separate roster-based estimator (this is MLB-specific and stays in this skill). Method in resources/methodology.md.
Sum projected season totals for each cat across roster
Best-response: Concede SV; push all 5 hitting + K + QS + ERA + WHIP. Do not chase closers as streamers.
Pattern 4: frustrated_active (active but losing -- motivated trader)
Signals: moves_per_week > 4 AND record_last_2_weeks W% < 0.35
Best-response: Prime trade partner. They'll respond to offers. Target their cooling stars (sell-high for them, buy-low for us).
Pattern 5: balanced (the default)
Signals: No strong punts; roster composition within 1 std of league average across all features
Best-response: Match cat-for-cat; matchup decided on weekly execution. Use variance-seeking when we're the underdog (matchup_win_probability < 0.40).
Guardrails
Classifier delegation purity. This skill MUST NOT implement Bayesian math. If you find yourself computing posteriors, likelihoods, or normalizations, stop -- those belong in opponent-archetype-classifier. This skill contributes the taxonomy (MLB-specific), feature extraction (Yahoo-specific), and output formatting. Any math beyond "sum projected season totals for cat_strength" is a smell.
Manual-notes preservation is non-negotiable. Users hand-author Sections 1, 5, 6, 8, 9 with strategic notes this skill cannot reproduce (e.g. "Jennifer's email bounced, suggest probe via DM"). Blind-overwriting those sections destroys user work. Always read-modify-write. Validate diff before commit: only frontmatter + Sections 2, 3, 4, 7 should change.
Graceful scrape failure. If a Yahoo page returns 4xx/5xx or the session is unauthenticated: do NOT guess. Mark the corresponding features as null, record the failed URL in a scrape_errors: block in frontmatter, and drop confidence by 0.2. The profile should still emit, just with lowered confidence. A partial profile is better than a missing one.
Sequential-update discipline. Last week's posterior becomes this week's prior -- always. Do NOT restart from taxonomy priors each week (that throws away 1-4 weeks of evidence). The one exception: if prior_profile.confidence < 0.20, restart (the prior profile is essentially garbage).
Correlated-feature handling.moves_per_week and faab_spent_pct are strongly correlated (active managers do both). Pass correlated_feature_pairs to the classifier so it down-weights. Same for sp_roster_share and closer_count (they trade off by roster-slot constraint).
Do not invent cat_strength from the archetype.cat_strength is a separate estimator based on actual roster composition, NOT derived from archetype. A balanced team with a thin OF has below-average SB; don't paper over that by inheriting "balanced = 50s across the board". Compute from roster.
Archetype unknown is valid. When classification_confidence < 40, write archetype: unknown with archetype_confidence reflecting the classifier output. Do not force a MAP on thin evidence. Downstream agents handle unknown by falling back to broad heuristics.
Citation requirement. Every emitted profile lists exact Yahoo URLs in source_urls. The weekly signal file lists all URLs across all 11 teams (dedupe the teams-page URL).
One-shot vs all-opponents mode. Single-team refreshes (on trade-offer arrival, FAAB competition observation) emit only the profile file -- no weekly summary signal. Weekly summary signal is emitted only after all 11 refreshes complete.
Team slugs stable. Slugs are lowercased + hyphenated team name, stable across the season (e.g., jennys-team, springfield-isotopes). If a manager renames their team mid-season, keep the original slug and store the new team_name in frontmatter -- do not rename the file (breaks downstream agent references).