METHOD / SOURCE CONTRACTS
How the brief is built.
Don't Die Fishing assembles public forecasts, observations, tide products, and cited regulation references into a compact planning view. The sections below describe the current contracts in the app; they do not grant permission to launch, navigate, or fish.
01 / SOURCE ROLES
Each source has a different job.
NWS supplies the forecast and active-alert inputs. DDF uses its point, forecast, hourly, grid, and alert paths for forecast wind, gusts, air temperature, precipitation, visibility inference, lightning inference, marine warnings, and the site time zone.
NOAA / NDBC supplies configured buoy observations. When a usable observation is available, it contributes observed wind, gusts, wave height, wave period, swell direction, and water temperature.
NOAA CO-OPS supplies configured station tide predictions, water temperature, and tidal-current predictions. EPA supplies the UV Index input; it is an outdoor-exposure planning signal, not a marine forecast.
Forecast data and regulation authority stay separate: public weather and water products inform the planning view, while the applicable state agency, code, and in-season action control fishing rules.
apps/web/src/lib/fetchers/aggregate.ts combines source fetches into a condition snapshot02 / UNITS + TIME
The display normalizes units, not authority.
Condition snapshots use knots for wind and current, feet for waves and tide height, miles for visibility, seconds for wave period, Fahrenheit for temperature, percent for precipitation probability, and the unitless EPA UV Index. Source-specific conversions happen at the fetch boundary so the scorer receives one consistent shape.
Source timestamps are not silently treated as one clock. NDBC observations are read as UTC; NWS forecast intervals carry their own time-zone metadata and offsets; CO-OPS products are requested with an explicit time-zone mode; and EPA UV rows are matched to local solar time using the site longitude. Site-local display times use the stored or resolved IANA time zone when one is available.
packages/shared/src/types.ts defines shared condition, vessel, and profile shapes, apps/web/src/lib/fetchers/aggregate.ts combines source fetches into a condition snapshot03 / FRESHNESS
Age and malformed timestamps fail closed.
A configured NDBC observation older than three hours, or dated more than fifteen minutes in the future, is treated as unavailable. NWS grid values must cover the current instant and pass strict timestamp and unit checks; otherwise that optional forecast signal is omitted. These are data-quality gates, not guarantees about future conditions.
The aggregate snapshot is stamped when the fetch completes, but that stamp does not make every source equally fresh. Public landing derivations accept only a bounded, non-future snapshot: its fetched_at must be no more than six hours old and no more than fifteen minutes in the future. An unavailable or malformed snapshot keeps the branded unavailable/illustrative state instead of displaying a made-up reading.
Regulation freshness is a separate contract: a normalized rule needs a recent source check, the applicable effective year, a valid site time zone, complete provenance, and non-ambiguous season windows before DDF describes a current status. Older or incomplete rows remain references to verify, not current authority.
apps/web/src/lib/fetchers/noaa-buoy.ts parses and freshness-checks NDBC observations, apps/web/src/lib/fetchers/nws-forecast.ts parses NWS forecast and alert data, apps/web/src/lib/landing-live-hero.ts guards public landing-page live derivations, apps/web/src/lib/fetchers/aggregate.ts combines source fetches into a condition snapshot04 / SCORING
The score is deterministic planning guidance.
DDF computes a 0–100 adverse-condition score for the selected vessel and profile. Lower is more favorable under that configuration: scores below 40 map to GO, 40–59 map to CAUTION, and 60–100 map to NO-GO. Those bands are DDF display thresholds, not official operating limits.
Hard vetoes run before weighted scoring. The current veto contract covers configured severe marine-warning phrases, high lightning risk, and extreme profile-relative readings: wind, gusts, waves, or current above 1.5× the selected threshold, visibility below 0.5×, or water temperature below 0.75×. A veto returns NO-GO/100 with a reason; it is still advisory and does not replace an official warning or judgment.
Available signals are weighted by the selected profile. A missing numeric signal is not turned into a favorable zero: it is marked unavailable, excluded from the weighted total, and the remaining available weights are renormalized. A missing warning array is not silently treated as “no warnings” in the landing live-data guard.
packages/shared/src/scoring/score.ts applies profile-aware adverse-condition scoring, packages/shared/src/scoring/thresholds.ts defines vessel and profile threshold defaults, packages/shared/src/scoring/vetoes.ts defines hard NO-GO conditions05 / VESSEL PROFILES
The vessel changes the lens.
The shared contract supports powerboat, sailboat, kayak, and paddleboard vessel types, with cautious, moderate, and experienced scoring profiles. Vessel type selects the default threshold set; scoring profile selects the default weighting posture. A saved vessel may also carry custom thresholds and weights.
“Cautious,” “moderate,” and “experienced” are configuration labels, not a certification of a person, vessel, or route. Choose the profile that reflects the actual craft, crew, and conditions, then compare the brief with official products and your own judgment.
packages/shared/src/types.ts defines shared condition, vessel, and profile shapes, packages/shared/src/scoring/thresholds.ts defines vessel and profile threshold defaults, packages/shared/src/scoring/weights.ts defines signal weighting profiles06 / MISSING DATA
Unavailable is an honest result.
Fetch failures, invalid values, stale observations, and missing optional fields resolve to null or an explicit unavailable result at the boundary. The interface uses labels such as “N/A,” “unavailable,” or “verify official rules” instead of inventing zeroes, substituting an unrelated reading, or presenting an empty warning response as proof of calm conditions.
Forecast-only planning windows are labeled as forecast data and do not imply that unforecast waves, tides, currents, water temperature, or UV values were observed. Current conditions and forward-looking forecasts are different evidence classes.
apps/web/src/lib/fetchers/aggregate.ts combines source fetches into a condition snapshot, packages/shared/src/scoring/score.ts applies profile-aware adverse-condition scoring07 / REGULATION PROVENANCE
Rules are references, not permission.
Regulation rows are kept separate from the conditions score. A normalized row can be evaluated only when it has a source URL, authority, source-updated date, source-check timestamp, matching effective year, valid IANA site time zone, and valid, non-overlapping season windows. The shared freshness window is seven days.
Legacy rows are retained as reference-only material and never authorize a current open/closed status. DDF links the cited state or federal source beside a listing and tells the reader to verify the applicable official rule, code, emergency order, and in-season action before fishing or retaining a catch.
The regulation catalog is therefore a sourced index of what DDF has recorded, not a complete rulebook and not legal permission. The public catalog exposes the source and its freshness context for each supported jurisdiction.
packages/shared/src/regulations.ts normalizes and evaluates regulation rows08 / CONFIDENCE + BOUNDARY
No numeric confidence is implied.
DDF does not currently publish a statistical confidence score or probability. GO, CAUTION, and NO-GO are deterministic labels from the selected profile and the signals that passed their data-quality gates; they do not mean “safe,” guaranteed, complete, or authorized.
Missing data reduces what can be evaluated; it is not evidence that the remaining data is more reliable. Read the source timestamps, inspect the official forecast and warnings, verify the applicable regulations, and apply professional maritime judgment before and during a trip.
This product is a planning aid. It is not emergency dispatch, a navigation service, a safety authorization, a legal decision, or a substitute for official weather, marine warnings, navigational notices, local regulations, or qualified judgment.
packages/shared/src/scoring/score.ts applies profile-aware adverse-condition scoring, apps/web/src/lib/fetchers/aggregate.ts combines source fetches into a condition snapshotCONTRACTS CHANGE WITH THE CODE · SOURCE LINKS ARE PROVIDED SO THE CURRENT RULES CAN BE CHECKED DIRECTLY