Layer 3 Step 5: weather modulation composed onto the park base
Completes the coupled environment: effective = park_base x weather_mod. Weather tilts the park, it never overrides it — a wind-out night at Oracle Park is still Oracle Park. PHASE 0 — both feeds are free and keyless. statsapi /venues gives every park's coordinates in one call; Open-Meteo returns hourly temperature, wind speed and wind direction for those coordinates hours before first pitch, which is when we project. Verified live. THE SPINE — two weather values, two purposes, never crossed. The FORECAST we held at projection time drives the live adjustment AND is what the instrument measures, because it is what we actually knew. It lands on the ledger row beside p_win. The ACTUAL goes only to game_context as raw material for future self-derived weather factors, and is read by nothing that scores a projection. Using the actual to measure tonight would be scoring ourselves on information we did not have. The actual is also pulled from Open-Meteo's ARCHIVE endpoint rather than the forecast endpoint, because asking a forecaster after the fact returns a re-forecast, not what happened. WIND IS PARK-ORIENTATION CONDITIONED. Wind direction is meteorological — the direction it comes FROM — so blowing out to centre means arriving from the opposite bearing. Getting that backwards would invert every wind adjustment in the system, so the 180-degree rotation is commented at the site and pinned by a test on all three cases: straight out, straight in, and crosswind. Centre-field bearings are public geometry, in the same class as the dome list; a park missing from the table gets no wind effect at all rather than a guessed one, and keeps its temperature effect. THREE HONEST DO-NOTHING STATES, all multiplier 1.0, none fabricating an effect. Dome: weather does not apply, and the PARK factor still does — verified that a domed venue keeps its sub-1.0 park base while weather stands down. Forecast absent: none available for this park and time. Sub-threshold: a real forecast below a meaningful bar, because manufacturing a 0.3% nudge on a light breeze is false precision. Weather also says nothing about a strikeout prop and returns not-applicable rather than a neutral it might later be tempted to fill. Conservative and ledger-tunable: every magnitude is an env var, the total is capped at 12%, and nothing here is asserted. This is a nominated challenger that earns its place on the instrument or is cut. Induced at Wrigley, whose centre field bears 32 degrees: wind from 212 at 15 mph computes as 15 mph straight out, weather 1.12 composed with park 1.06 for an effective 1.187 and a +0.043 nudge; the under mirrors exactly; the pitcher's home-runs-allowed prop moves with the hitter's, since both are P(over) on a ball leaving the park. Wind in drops the coefficient to 0.955. A calm 72-degree evening, a dome, and a missing forecast all return 1.0 by three different honest routes, with the park base still applying in each. One correction to the order worth recording: it describes a wind-out night as helping the hitter and hurting "the pitcher there's HR-allowed" as opposite sides. In prop terms both go the same way — the HR-allowed OVER is more likely too. The sign lives in the stat, exactly as established for park factors, and the implementation follows that rather than the phrasing. Migration 036. Tests 3707 passed / 299 suites, web build exit 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCNgGSt5qvcLxaeQqa7Zpj
This commit is contained in:
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user