Genius Level
Every input, formula, threshold, and applied calculation in SHA's river/weather/forecast/run intelligence stack. One scroll, no clicks, no caches. Designed to be diagnostic-first, educational-second.
1 · Live snapshot — Cuyahoga River @ Independence
The single most recent river_conditions row for this river.
Fed every 15 min by the rivers:update command which combines USGS
instantaneous values (flow, gauge height, water temp, parameter 00045 for rain bucket) with
OpenWeather current conditions (air temp, weather, wind, humidity, barometric pressure).
2 · Recommendation breakdown
The fishing rating shown on each river page comes from
FishingRecommendationService::getRecommendation(). Four
independently scored components plus a barometric-pressure modifier produce a 0–11 raw score, which is
clamped and cut into Excellent / Good / Fair / Poor. Below is the live decomposition for this river.
"Running 357 CFS, water is clear, 69°F — prime summer feeding temp. Worth the gas money. Pick your water carefully. Clear water means spooky fish. Approach low and slow. Legend Has It, He's Still Mending."
Per-component contribution
| Component | Points | Why |
|---|---|---|
| flow | 1 | |
| temp | 3 | |
| clarity | 3 | |
| weather | 0 | |
| pressure | 0 | |
| flow_value | 357 | |
| temp_value | 68.5 | |
| clarity_value | Clear |
Barometric pressure analyzer
Scoring rules
- flow
- In optimal zone = 4 · within 30% = 3 · within 60% = 2 · outside = 1 · above p95×1.5 = 0 (blown).
- temp
- 38–55°F = 3 (prime: covers winter holdover + spring run) · 33–58°F = 2 · 30–62°F = 1 · outside = 0.
- clarity
- Stained = 3 (steelhead green) · Clear = 2 · Muddy = 0.
- weather
- Cloudy/Overcast = 1 · else = 0.
- pressure
- Rapidly falling = +2 · falling = +1 · stable = 0 · rising = -1 · rapidly rising = -1.
- rating_cuts
- Excellent ≥ 9 · Good ≥ 6 · Fair ≥ 3 · Poor < 3 (max 11 after clamp).
3 · Statistics engine
Cached in river_flow_stats, regenerated nightly at 03:00 ET by
flow:compute-stats. The pipeline pulls a 3-year window of hourly-
downsampled USGS flow, removes Tukey outliers at 3× IQR on log-flow, then computes percentiles, a
20-bin log-space histogram, Q-Q quantiles vs. a fitted normal, and (if ≥ 20 historical "Good" reports
exist) promotes the optimal zone from a heuristic p15–p30 to the empirical p10–p90 of those reports.
Percentile distribution
| P | cfs |
|---|---|
| pp5 | 357 |
| pp10 | 379 |
| pp25 | 428 |
| pp50 | 714 |
| pp75 | 1,096 |
| pp90 | 1,745 |
| pp95 | 2,518 |
Flow distribution histogram (log-space, 3 yr)
Green bars overlap the optimal zone. Bars are equal-width in log-flow space.
Today's flow placement
Current flow 357 cfs sits at the p5 of the 3-year record. Green band = optimal zone.
4 · Weather integration
Three independent feeds power the per-river weather story. NWS gridpoint forecasts (refreshed every 3 hours) supply 7-day periods + 48 hours of hourly data. AHPS stage forecasts give 5-day predicted flow / gauge height. SPC convective outlooks tier the river's lat/lon by tornado / wind / hail risk for days 1–3. Active alerts are de-duplicated against expired headlines.
NWS 7-day forecast
| Period | Temp | Wind | Forecast |
|---|---|---|---|
| Overnight | 64°F | 2 mph S | Mostly Clear |
| Sunday | 87°F | 2 to 7 mph W | Mostly Sunny then Slight Chance Showers And Thunderstorms |
| Sunday Night | 68°F | 1 to 6 mph SW | Slight Chance Showers And Thunderstorms then Partly Cloudy |
| Monday | 90°F | 2 to 8 mph SW | Partly Sunny then Slight Chance Showers And Thunderstorms |
| Monday Night | 70°F | 8 mph SW | Chance Showers And Thunderstorms then Showers And Thunderstorms |
| Tuesday | 83°F | 7 to 13 mph NW | Showers And Thunderstorms |
| Tuesday Night | 65°F | 8 to 13 mph N | Chance Showers And Thunderstorms |
5 · Run indicator (alley-wide)
Latest 24h average lake-surface temp from NDBC buoys + C-MAN stations, compared against 7-day delta and 55°F threshold crossing detection. State changes drive copy on every river page.
Lake Erie
| NDBC-45142 | 72.3°F | Jul 26 7:00am |
| NDBC-45005 | 75.6°F | Jul 26 7:00am |
| NDBC-45005 | 75.6°F | Jul 26 6:50am |
| NDBC-MRHO1 | 77.2°F | Jul 26 6:48am |
| NDBC-FAIO1 | 75°F | Jul 26 6:48am |
| NDBC-CNDO1 | 73.4°F | Jul 26 6:48am |
Lake Ontario
| NDBC-45139 | 66.9°F | Jul 26 7:00am |
| NDBC-45012 | 66.2°F | Jul 26 7:00am |
| NDBC-45012 | 66.4°F | Jul 26 6:40am |
| NDBC-45012 | 66.2°F | Jul 26 6:30am |
| NDBC-45012 | 66.4°F | Jul 26 6:10am |
| NDBC-45139 | 66.9°F | Jul 26 6:00am |
Seven-state classifier
- pre_run_fall
- Fish staging in lake; tribs empty.
- run_starting_fall
- First fish entering tribs (fall pulse).
- run_active_fall
- Active fall run.
- holdover
- Fish wintering in tribs between fall + spring.
- run_starting_spring
- Spring run starting (post-holdover surge).
- run_active_spring
- Active spring run.
- run_ending
- Drop-back; spawned fish leaving for the lake.
- off_season
- Lake-bound; tribs warm; warmwater season.
6 · Storm detection (alley-wide)
ActiveStormDetector fires four parallel triggers against
river_precip_observations, NWS active alerts, and 6-hour flow deltas.
Any single trigger flips the storm card to active; severity is then classified by the most aggressive
signal across all 31 rivers. Precip readings flow from a 4-source priority chain — fresher, more
accurate sources override stale ones.
"3 rivers rising 11.6×+ in 6h"
Selected river lifecycle
Storm lifecycle state transitions
Storm Lifecycle State Matrix
| River | State | Severity | Signals | Confidence | Headline |
|---|---|---|---|---|---|
| Ashtabula River | quiet | - | - | 90% | - |
| Black River | quiet | - | - | 90% | - |
| Black River (Watertown) | quiet | - | regional_bucket_active | 90% | - |
| Brandy Run near Girard | quiet | - | - | 90% | - |
| Buffalo Creek | quiet | - | - | 90% | - |
| Canadaway Creek | quiet | - | - | 90% | - |
| Cattaraugus Creek | quiet | - | - | 90% | - |
| Cazenovia Creek | quiet | - | - | 90% | - |
| Chagrin River @ Willoughby | quiet | - | - | 90% | - |
| Chautauqua Creek | quiet | - | - | 90% | - |
| Conneaut Creek | quiet | - | - | 90% | - |
| Crooked Creek | quiet | - | regional_bucket_active | 90% | - |
| Cuyahoga River @ Independence | quiet | - | - | 90% | - |
| Eighteen Mile Creek | quiet | - | - | 90% | - |
| Eighteenmile Creek (Niagara) | quiet | - | regional_bucket_active | 90% | - |
| Elk Creek | active | moderate | flow_rising_fast, regional_bucket_active | 95% | Flow up 270% in 6h. |
| Euclid Creek | quiet | - | - | 90% | - |
| Genesee River | active | moderate | flow_rising_fast, regional_bucket_active | 95% | Flow up 1060% in 6h. |
| Grand River near Painesville | quiet | - | - | 90% | - |
| Huron River | quiet | - | - | 90% | - |
| Irondequoit Creek | watching | - | forecast_precip_0_3, regional_bucket_active | 67% | 0.5" rain expected by 3 pm. Gauges still calm. |
| Johnson Creek | quiet | - | regional_bucket_active | 90% | - |
| Oak Orchard Creek | quiet | - | regional_bucket_active | 90% | - |
| Rocky River near Berea | quiet | - | - | 90% | - |
| Salmon River | quiet | - | regional_bucket_active | 90% | - |
| Sandy Creek (Adams) | quiet | - | regional_bucket_active | 90% | - |
| Sandy Creek (Hamlin) | quiet | - | regional_bucket_active | 90% | - |
| Silver Creek | quiet | - | - | 90% | - |
| Twenty Mile Creek | active | moderate | flow_rising_fast, regional_bucket_active | 95% | Flow up 270% in 6h. |
| Vermilion River @ Vermilion | quiet | - | - | 90% | - |
| Walnut Creek | quiet | - | regional_bucket_active | 90% | - |
Precipitation rate — last 24 hours (NWS publishes in 6h intervals; USGS hourly where available)
Y axis is in/hr precipitation, auto-scaled but always includes the broad-rain trigger so quiet days still have context. The cyan line is the alley-wide average; gray ticks above each cyan dot show how high the single wettest river was running at that observation. When cyan crosses amber → broad-front rain. When a gray tick crosses red → one river is in a heavy cell. Sparse points are real — NWS gridpoint QPE only updates every 6 hours per river; the hourly USGS rows fill in for the handful of rivers whose gauges publish precipitation.
Triggers
- Trigger 1A — Heavy MRMS rate
- ≥ 1 river over 0.5 in/hr in last 30 min.
- Trigger 1B — Broad rain
- ≥ 3 rivers with precipitation_1h > 0.10".
- Trigger 2 — NWS alert
- ≥ 1 active alert covering any river.
- Trigger 3 — Flow rise
- ≥ 1 river with current flow ≥ 1.5× flow 6 hours ago.
Severity classifier
- severe
- NWS Extreme/Severe alert · MRMS ≥ 1.0 in/hr · ≥ 5 rivers rising · ≥ 8 raining · ≥ 3 heavy MRMS rivers
- moderate
- Any active alert · MRMS ≥ 0.5 in/hr · ≥ 1 rising · ≥ 5 raining
- light
- Default when active but none of the above
Precipitation source priority
- mrms — Open-Meteo Lite (15-min observations) — 10 min staleness window
- usgs — USGS parameter 00045 from gauges with rain buckets — 30 min
- nws_obs — NWS gridpoint quantitativePrecipitation past intervals — 90 min
- nws_fcst — NWS gridpoint forecast (final fallback) — 240 min
7 · Alley Index (alley-wide)
Percentile rank of today's underlying conditions composite (mean of per-river fishing scores 0–100) against the historical record on this calendar window (±15 days, all years). Below 10 comparable days in the window the Index falls back to the raw underlying score so the page always shows a meaningful number.
Band cuts
| Band | Cut | Meaning |
|---|---|---|
| Excellent | ≥ 90 | Top 10% of comparable days ever recorded. |
| Good | ≥ 70 | Top 30%. |
| Average | ≥ 30 | Middle 40%. |
| Poor | ≥ 10 | Bottom 30%. |
| Blown | ≥ 0 | Bottom 10%. |
Last 30 days
Older → newer left to right. Color follows band cuts.
8 · Forecast verification (alley-wide)
Most-recent NWS prediction for each (river, date) in the last 14 days, sorted past→future. The verifier joins each prediction to MAX/MIN(air_temp_f) + MAX(precipitation_1h) from river_conditions on that date. Δ column compares observed vs predicted. Known upstream gap: predicted precipitation inches are unreliable (NWS forecast text rarely includes a clean inches value, so the snapshotter falls back to 0). Use precip probability as the better forecast signal.
| Date | River | Predicted (hi/lo · precip) | Observed (hi/lo · max 1h) | Δ vs predicted |
|---|---|---|---|---|
| 2026-08-01 | Ashtabula River | 80°/— · 24% POP · 8 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Black River | 84°/— · 29% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-08-01 | Black River (Watertown) | 80°/— · 31% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Brandy Run near Girard | 81°/— · 28% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Buffalo Creek | 81°/— · 33% POP · 6 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Canadaway Creek | 79°/— · 30% POP · 8 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Cattaraugus Creek | 83°/— · 39% POP · 3 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Cazenovia Creek | 81°/— · 34% POP · 6 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Chagrin River @ Willoughby | 83°/— · 24% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-08-01 | Chautauqua Creek | 78°/— · 29% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Conneaut Creek | 81°/— · 25% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Crooked Creek | 80°/— · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Cuyahoga River @ Independence | 86°/— · 28% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-08-01 | Eighteen Mile Creek | 80°/— · 35% POP · 5 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Eighteenmile Creek (Niagara) | 82°/— · 26% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Elk Creek | 81°/— · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Euclid Creek | 81°/— · 24% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Genesee River | 82°/— · 32% POP · 6 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Grand River near Painesville | 82°/— · 24% POP · 8 mph NE | (future — not yet verifiable) | |
| 2026-08-01 | Huron River | 84°/— · 29% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-08-01 | Irondequoit Creek | 84°/— · 32% POP · 6 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Johnson Creek | 80°/— · 25% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Oak Orchard Creek | 81°/— · 26% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Rocky River near Berea | 84°/— · 29% POP · 9 mph NE | (future — not yet verifiable) | |
| 2026-08-01 | Salmon River | 80°/— · 35% POP · 5 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Sandy Creek (Adams) | 79°/— · 28% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Sandy Creek (Hamlin) | 82°/— · 27% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Silver Creek | 79°/— · 32% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Twenty Mile Creek | 78°/— · 27% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-08-01 | Vermilion River @ Vermilion | 83°/— · 28% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-08-01 | Walnut Creek | 80°/— · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Ashtabula River | 79°/68° · 24% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-07-31 | Black River | 83°/64° · 17% POP · 7 mph SE | (future — not yet verifiable) | |
| 2026-07-31 | Black River (Watertown) | 79°/62° · 18% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Brandy Run near Girard | 80°/63° · 26% POP · 7 mph S | (future — not yet verifiable) | |
| 2026-07-31 | Buffalo Creek | 81°/64° · 18% POP · 6 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Canadaway Creek | 78°/65° · 22% POP · 8 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Cattaraugus Creek | 82°/62° · 20% POP · 5 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Cazenovia Creek | 81°/64° · 18% POP · 6 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Chagrin River @ Willoughby | 82°/66° · 21% POP · 7 mph SE | (future — not yet verifiable) | |
| 2026-07-31 | Chautauqua Creek | 77°/67° · 23% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Conneaut Creek | 80°/67° · 25% POP · 7 mph NE | (future — not yet verifiable) | |
| 2026-07-31 | Crooked Creek | 79°/64° · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Cuyahoga River @ Independence | 84°/66° · 18% POP · 7 mph NE | (future — not yet verifiable) | |
| 2026-07-31 | Eighteen Mile Creek | 80°/63° · 20% POP · 5 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Eighteenmile Creek (Niagara) | 81°/63° · 18% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Elk Creek | 80°/65° · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Euclid Creek | 80°/68° · 21% POP · 7 mph E | (future — not yet verifiable) | |
| 2026-07-31 | Genesee River | 81°/64° · 14% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Grand River near Painesville | 81°/65° · 22% POP · 8 mph E | (future — not yet verifiable) | |
| 2026-07-31 | Huron River | 83°/64° · 18% POP · 6 mph SE | (future — not yet verifiable) | |
| 2026-07-31 | Irondequoit Creek | 82°/64° · 13% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Johnson Creek | 80°/66° · 16% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Oak Orchard Creek | 80°/65° · 16% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Rocky River near Berea | 83°/65° · 18% POP · 8 mph E | (future — not yet verifiable) | |
| 2026-07-31 | Salmon River | 78°/60° · 16% POP · 6 mph E | (future — not yet verifiable) | |
| 2026-07-31 | Sandy Creek (Adams) | 78°/62° · 15% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Sandy Creek (Hamlin) | 80°/65° · 16% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-31 | Silver Creek | 78°/64° · 22% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Twenty Mile Creek | 77°/67° · 25% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-31 | Vermilion River @ Vermilion | 81°/65° · 19% POP · 7 mph SE | (future — not yet verifiable) | |
| 2026-07-31 | Walnut Creek | 79°/68° · 26% POP · 7 mph SW | (future — not yet verifiable) | |
| 2026-07-30 | Ashtabula River | 77°/66° · 10% POP · 14 mph NW | (future — not yet verifiable) | |
| 2026-07-30 | Black River | 80°/62° · 5% POP · 10 mph NE | (future — not yet verifiable) | |
| 2026-07-30 | Black River (Watertown) | 76°/60° · 34% POP · 9 mph N | (future — not yet verifiable) | |
| 2026-07-30 | Brandy Run near Girard | 77°/62° · 11% POP · 9 mph N | (future — not yet verifiable) | |
| 2026-07-30 | Buffalo Creek | 76°/60° · 13% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-30 | Canadaway Creek | 76°/63° · 12% POP · 9 mph W | (future — not yet verifiable) | |
| 2026-07-30 | Cattaraugus Creek | 77°/59° · 15% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-30 | Cazenovia Creek | 77°/61° · 13% POP · 7 mph W | (future — not yet verifiable) | |
| 2026-07-30 | Chagrin River @ Willoughby | 79°/63° · 8% POP · 9 mph N | (future — not yet verifiable) | |
| 2026-07-30 | Chautauqua Creek | 74°/65° · 10% POP · 9 mph NW | (future — not yet verifiable) | |
| 2026-07-30 | Conneaut Creek | 77°/66° · 11% POP · 9 mph NW | (future — not yet verifiable) | |
| 2026-07-30 | Crooked Creek | 77°/64° · 12% POP · 8 mph N | (future — not yet verifiable) | |
| 2026-07-30 | Cuyahoga River @ Independence | 81°/63° · 6% POP · 10 mph NE | (future — not yet verifiable) | |
| 2026-07-30 | Eighteen Mile Creek | 76°/60° · 13% POP · 6 mph W | (future — not yet verifiable) | |
| 2026-07-30 | Eighteenmile Creek (Niagara) | 77°/61° · 13% POP · 10 mph NW | (future — not yet verifiable) | |
| 2026-07-30 | Elk Creek | 78°/64° · 11% POP · 9 mph N | (future — not yet verifiable) | |
| 2026-07-30 | Euclid Creek | 77°/65° · 7% POP · 9 mph NW | (future — not yet verifiable) | |
| 2026-07-30 | Genesee River | 76°/62° · 22% POP · 10 mph NW | (future — not yet verifiable) |
9 · Conditions archive (alley-wide)
Tiered retention so the database doesn't grow unbounded but the long-history aggregates that power the
Alley Index, forecast verifier, and storm-pulse detector remain intact. Raw river_conditions
prune weekly via rivers:clean; hourly + daily rollups are forever.
Retention policy
- raw river_conditions
- 90 days (pruned weekly via rivers:clean)
- gauge_readings
- 90 days
- lake_temp_snapshots
- forever (small volume)
- precip_observations
- raw 90 days; hourly + daily rollups forever
- ahps_forecasts
- forever
- alley_index_snapshots
- forever
- spc_outlooks
- forever
- nws_alerts
- forever (with ended_at marker)
Row counts (live)
| river_conditions | 516,207 |
| gauge_readings | 778,400 |
| lake_temp_snapshots | 40,952 |
| precip_observations | 15,907 |
| ahps_forecasts | 2,549 |
| alley_index_snapshots | 182 |
| spc_outlooks | 60 |
| nws_alerts | 689 |
10 · Data sources & cadence (operational)
Every external feed feeding SHA's intelligence stack, with the artisan command that drives it, last-fetch timestamp, and total row count. If a "last_at" is hours behind cadence, that source is stalled.
| Source | Cadence | Driver | Last at | Rows |
|---|---|---|---|---|
| USGS instantaneous values | 15 min | rivers:update | Jul 26 7:45am | 778,400 |
| OpenWeather current | 15 min | rivers:update | Jul 26 7:45am | 516,207 |
| NWS 7-day + hourly forecast | 3 hours | forecasts:fetch | Jul 26 5:03am | 32 |
| NWS AHPS predicted flow | 6 hours | ahps:fetch | Jul 25 11:31am | 2,549 |
| NWS active alerts | 15 min | alerts:fetch-nws | Jul 21 8:19pm | 689 |
| SPC convective outlooks | 3 hours | spc:fetch-outlook | Jul 26 5:19am | 60 |
| NDBC + C-MAN lake temps | 1 hour | noaa:fetch-buoys | Jul 26 7:00am | 40,952 |
| River precip (USGS / NWS / MRMS-Lite) | 5–60 min | rivers:update + precip:fetch-nws + local Open-Meteo worker | Jul 26 2:00am | 15,907 |
| Alley Index snapshot | hourly + daily 04:50 ET | index:compute | Jul 26 7:51am | 182 |
| Run state classifier | daily 06:30 ET | run-state:compute | Jul 25 | 156 |
11 · Constants reference (every threshold in one place)
Every magic number that drives a SHA decision, with the file it lives in. Edit the source to change a threshold — this page reflects the live code path. Grouped by subsystem.
| Group | Constant | Value | Where |
|---|---|---|---|
| Flow scoring | In optimal zone | 4 points | IndexCalculatorService::scoreCondition |
| Flow scoring | Within 30% of optimal | 3 points | IndexCalculatorService::scoreCondition |
| Flow scoring | Within 60% of optimal | 2 points | IndexCalculatorService::scoreCondition |
| Flow scoring | Above p95 × 1.5 | Blown (0) | IndexCalculatorService::scoreCondition |
| Temp scoring | Prime band (winter + spring) | 38–55°F = 3 | FishingRecommendationService::analyzeTemperature |
| Temp scoring | Good band | 33–58°F = 2 | FishingRecommendationService::analyzeTemperature |
| Temp scoring | Marginal band | 30–62°F = 1 | FishingRecommendationService::analyzeTemperature |
| Clarity | Clear / Stained ratio | < 1.4× p50 | RiverMonitorService::determineClarity |
| Clarity | Stained / Muddy ratio | < 2.8× p50 | RiverMonitorService::determineClarity |
| Pressure | Rapidly falling | ≤ -1.0 hPa/hr | PressureService |
| Pressure | Falling | ≤ -0.3 hPa/hr | PressureService |
| Pressure | Score modifier (rapidly falling) | +2 points | PressureService |
| Storm card | Heavy-MRMS threshold | 0.5 in/hr | ActiveStormDetector::HEAVY_RATE_INCHES_PER_HOUR |
| Storm card | Heavy-MRMS lookback | 30 min | ActiveStormDetector::HEAVY_RATE_LOOKBACK_MINUTES |
| Storm card | Broad-rain threshold | 0.10"/hr | ActiveStormDetector::RAIN_THRESHOLD_INCHES |
| Storm card | Broad-rain river count | ≥ 3 | ActiveStormDetector::MIN_RAIN_RIVERS |
| Storm card | Flow-rise factor | 1.5× vs 6h ago | ActiveStormDetector::FLOW_RISE_FACTOR |
| Storm lifecycle | Watching forecast precip | ≥ 0.30" in 24h | StormLifecycleService::forecastPrecipSignal |
| Storm lifecycle | Watching AHPS rise | ≥ 2× current flow | StormLifecycleService::watchingSignals |
| Storm lifecycle | Recovery lookback | 72 hours | StormLifecycleService::recoveringSignal |
| Storm lifecycle | Recovery normalized flow | ≤ optimal high × 1.15 | StormLifecycleService::flowIsNormalized |
| Run indicator | Lake threshold | 55°F | RunStateClassifier |
| Alley Index | Calendar window | ±15 days, all years | IndexPercentileService::WINDOW_DAYS |
| Alley Index | Min pool for percentile | 10 days | IndexPercentileService::MIN_POOL |
| Alley Index | Excellent band | ≥ 90 | IndexPercentileService::descriptorFor |
| Alley Index | Good band | 70–89 | IndexPercentileService::descriptorFor |
| Alley Index | Average band | 30–69 | IndexPercentileService::descriptorFor |
| Alley Index | Poor band | 10–29 | IndexPercentileService::descriptorFor |
| Alley Index | Blown band | 0–9 | IndexPercentileService::descriptorFor |
| Forecast verify | Snapshot time | Daily 05:15 ET | routes/console.php |
| Optimal zone | Empirical promotion threshold | ≥ 20 Good reports | RiverFlowStatistics |
| Stats engine | Window | 3 years | RiverFlowStatistics |
| Stats engine | Outlier removal | 3× IQR on log-flow | RiverFlowStatistics |
| Stats engine | Histogram bins | 20 (log-space) | RiverFlowStatistics |