skills/mlb-signal-emitter/SKILL.md
--- name: mlb-signal-emitter description: Validates and persists signal files to the yahoo-mlb signals directory. Every MLB skill calls this skill before writing a signal. Enforces the signal-framework.md schema -- required YAML frontmatter fields (type, date, emitted_by, confidence, source_urls), range-checks numeric signals (0-100 unipolar, -100 to +100 bipolar), verifies variant_synthesis metadata, and enforces file naming. On validation failure, does not persist and routes a failure entry to
npx skillsauth add lyndonkl/claude skills/mlb-signal-emitterInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Scenario: mlb-player-analyzer has computed a daily_quality signal for Junior Caminero on 2026-04-17 and wants to persist it.
Inputs passed to this skill:
type: playerdate: 2026-04-17emitted_by: mlb-player-analyzervariant_synthesis: true, variants_fired: [advocate, critic]form_score: 68, matchup_score: 74, opportunity_score: 62, daily_quality: 69, regression_index: +18, confidence: 0.78source_urls: [baseballsavant..., fangraphs..., mlb.com/gameday...]Validation pass (what this skill checks):
| Check | Result |
|---|---|
| YAML frontmatter parses | PASS |
| type is in allowed enum | PASS (player) |
| date is ISO YYYY-MM-DD | PASS |
| emitted_by present | PASS |
| confidence in [0.0, 1.0] | PASS (0.78) |
| source_urls is non-empty list | PASS (3 URLs) |
| variant_synthesis: true implies variants_fired has >= 1 | PASS (2 fired) |
| All numeric signals in declared range | PASS (all 0-100 signals clamped; regression_index in +-100) |
| File path matches signals/YYYY-MM-DD-<type>.md convention | PASS |
Action: Write to ~/Documents/Projects/yahoo-mlb/signals/2026-04-17-player-caminero.md and return the absolute path.
Failure scenario: If confidence: 1.4 had been passed, validation fails. The skill does NOT write the file. It calls mlb-decision-logger with a failure entry: kind: signal_validation_failure, signal_type: player, reason: confidence out of range (1.4 not in [0.0, 1.0]), emitter: mlb-player-analyzer, and returns an error to the calling agent.
Copy this checklist and track progress:
Signal Emission Progress:
- [ ] Step 1: Receive signal payload from upstream skill/agent
- [ ] Step 2: Validate YAML frontmatter (required fields)
- [ ] Step 3: Range-check all numeric signals
- [ ] Step 4: Validate variant synthesis metadata
- [ ] Step 5: Determine and validate file path
- [ ] Step 6: Write file OR log validation failure
Step 1: Receive signal payload
The caller hands in three things: (1) YAML frontmatter key-value pairs, (2) signal body (markdown tables), (3) intent (e.g., "this is a final synthesized signal" vs. "this is an intermediate variant dump"). See resources/template.md for the canonical input shape.
Step 2: Validate YAML frontmatter
Confirm all required keys are present and well-typed. See resources/methodology.md for the full list.
type present and in the allowed enum (lineup, waivers, streaming, trade, category-plan, playoff-push, player, matchup, regression, two-start, closer, faab, cat-state)date present and formatted YYYY-MM-DDemitted_by present and references a known skill or agentconfidence present as a float in [0.0, 1.0]source_urls present as a non-empty list of URLsStep 3: Range-check numeric signals
Every numeric signal in the body must fall inside its declared range. See resources/methodology.md for the per-signal range table (it mirrors signal-framework.md).
Step 4: Validate variant synthesis metadata
If this is a synthesized final signal, it must declare which variants produced it.
variant_synthesis: true, variants_fired is a list with >= 1 entryvariant_synthesis: true, synthesis_confidence is present and in [0.0, 1.0]variant_synthesis: false, the file is an intermediate variant dump; filename must include the variant suffix (see Step 5)red_team_findings (if present) is a list of objects with severity, likelihood, score, note fieldsStep 5: Determine and validate file path
The canonical path is ~/Documents/Projects/yahoo-mlb/signals/YYYY-MM-DD-<type>.md. For an intermediate variant dump, use YYYY-MM-DD-<type>-<variant>.md. For per-player or per-game files, an optional identifier suffix is allowed: YYYY-MM-DD-<type>-<identifier>.md.
date and type in frontmatteroverwrite: truesignals/ directoryStep 6: Write file OR log validation failure
If all checks pass: write the file, return the absolute path. If any check fails: do NOT write, call mlb-decision-logger with a structured failure entry, return an error object to the caller. See resources/methodology.md for the failure log schema.
mlb-decision-logger, return errorPattern 1: Per-player daily signal (type: player)
YYYY-MM-DD-player-<lastname>.md (e.g., 2026-04-17-player-caminero.md)daily_quality, plus the three components (form_score, matchup_score, opportunity_score)mlb-player-analyzer -- so variant_synthesis: true and variants_fired: [advocate, critic]Pattern 2: Daily lineup roll-up (type: lineup)
YYYY-MM-DD-lineup.mdsynthesis_confidence reflects agreement between the advocate (bat-everyone) and critic (sit-risky) variantsPattern 3: Intermediate variant dump (variant suffix in filename)
YYYY-MM-DD-<type>-advocate.md or YYYY-MM-DD-<type>-critic.mdvariant_synthesis: false (this IS a variant, not a synthesis)emitted_by names the agent and variant (e.g., mlb-lineup-optimizer/advocate)variant_synthesis: truePattern 4: Low-confidence graceful degrade
confidence <= 0.3 and a red_team_findings entry flagging the missing data sourceNever silently drop a signal. If validation fails, the failure must be logged via mlb-decision-logger so the calibration review can see what was rejected and why. A signal that never gets written AND never gets logged is invisible to the team.
Do not re-derive signal values. This skill is a validator and file-writer only. It never computes daily_quality or any other signal itself. If an upstream skill passes in a half-computed signal, reject it rather than filling in the blanks.
Reject unknown type values. The enum in signal-framework.md is the authoritative list. If a caller passes type: vibe-check, reject and log. Adding a new signal type requires updating signal-framework.md first, then this skill's validator.
Range checks are hard limits. A form_score of 105 is not "close enough" -- it indicates a bug upstream (probably forgot to normalize). Reject and log. Do NOT clamp-and-accept.
confidence is required, not optional. Even a perfectly-computed signal with three source URLs must carry a confidence float. A missing confidence is a validator failure, not a warning.
source_urls must be a non-empty list. Per CLAUDE.md rule 1 ("Web-search everything"), every factual signal is backed by a live source. An empty source_urls list means the signal was not grounded -- reject and log.
Variant synthesis claims must be provable. If variant_synthesis: true but variants_fired is empty or missing, that is a lie about the team's process. Reject and log.
Do not overwrite without explicit consent. If a signal already exists at the target path, refuse to overwrite unless the caller passes overwrite: true. This prevents losing an earlier morning's signal when a mid-day re-run happens.
Required frontmatter fields (always):
type (enum)date (YYYY-MM-DD)emitted_by (string)confidence (float 0.0-1.0)source_urls (non-empty list)Required when variant_synthesis: true:
variants_fired (list, >= 1)synthesis_confidence (float 0.0-1.0)File path conventions:
signals/YYYY-MM-DD-<type>.mdsignals/YYYY-MM-DD-<type>-<id>.mdsignals/YYYY-MM-DD-<type>-<variant>.mdSignal ranges (see resources/methodology.md for the full table):
On validation failure:
{kind: signal_validation_failure, signal_type, reason, field, expected, actual, emitter, timestamp}.mlb-decision-logger with the failure entry.Key resources:
Inputs required:
overwrite flag (default false)Outputs produced:
tracker/decisions-log.md via mlb-decision-loggerdevelopment
--- name: zettel-note description: The note-writing discipline for this vault's evergreen knowledge graph, modeled on a Zettelkasten reading companion and governed by the vault conventions. Enforces declarative-claim titles, one claim per note (atomicity), own-words prose with no block quotes, the piped [[slug|Title]] link form, the labeled link-relationship vocabulary (Confirms/Contradicts/Extends/Context/Prerequisite/Builds-on/Applies/Example-of/Contrasts-with), 3-6 links per note, and search-
development
Plans between-round FIFA World Cup Fantasy transfers — budgets the round's free transfer(s), forces out players whose nation has been eliminated, chases fixture-swing drops, upgrades on value, and decides when a rebuild is large enough to fire the Wildcard instead of spending free transfers one at a time. Ranks candidate in/out pairs by EV gain over each player's remaining survival horizon (delta xEV weighted by progression_carry) MINUS transfer cost (a free transfer is cheap, a points hit is real, churning the squad for marginal swings is a critic flag), and tags forced/fixture/upgrade priority. Emits a `transfer-plan` signal. Use when called by wc-squad-architect (whose transfer work this skill is the engine for) and by the strategists in the populate stage when their candidate is transfer-adjacent rather than a full rebuild.
testing
Reads and updates the FIFA World Cup Fantasy tournament state machine (footballfantasy/context/tournament-state.md) — the temporal backbone tracking phase (pre-tournament → group MD1-3 → R32 → R16 → QF → SF → final), budget ($100m group / $105m knockouts), nation cap (3 group, loosening in knockouts), chips remaining, surviving nations, each owned player's elimination-risk horizon, and deadlines. Validates state on load (count/feasibility checks), applies phase transitions, and appends to the append-only state log (never silent overwrite). Use to load state at the start of a run and to commit state changes after the manager makes a move.
development
Validates and persists FIFA World Cup Fantasy signal files to signals/YYYY-MM-DD-<type>.md. Checks the required frontmatter (type, round, date, emitted_by, confidence, source_urls), range-checks declared numeric signals, confirms every factual claim carries a source URL or "manager-provided", rejects unknown signal types, and refuses to persist a signal that fails validation (logging the failure instead). Keeps the inter-agent signal layer auditable so downstream agents can trust what they read and never re-derive it. Use whenever an agent or skill writes a signal.