# Near-Term Report Roadmap ## Purpose This roadmap defines planned work to add a rolling `near_term` report focused on the next several hours. The feature is not implemented yet, so this document lives under `docs/roadmap/`. The goal is a frequently generated report that helps readers understand what matters in the immediate future: current conditions, hourly evolution, precipitation timing, applicable hazards, applicable SPC risk products, and the most relevant short-term narrative context. ## Target Behavior Add a generated report with: - report ID: `near_term` - display name: `Near-Term Report` - prompt ID: `weather.near_term_report` - artifact group: `near-term` - batch output name: `near-term.md` - default valid-period length: 6 hours - valid period: `[generation_time, generation_time + nearTermHours)` The report should use a package-owned constant for the valid-period length, for example: ```go const nearTermHours = 6 ``` Do not make the duration configurable in the first implementation. The constant exists so the value can be changed later to 4 or 8 hours without changing valid-period logic in multiple places. ## Locked Decisions - The report ID is `near_term`. - The report is rolling and generation-time anchored, not civil-day anchored. - The first implementation covers the next 6 hours through a constant. - The report should be generated explicitly by CLI command before deciding whether it belongs in scheduled batches. - The first implementation should declare `rolling_window` comparison policy but should not emit Recent Changes output for `near_term`. - Alert and SPC products should be included only when their valid periods overlap the resolved near-term report period. - SPC discussion text should keep the existing categorical-risk threshold rule and should still require overlap with the near-term report period. - The AFD stanza should include key messages and short term text by default. - Daily-only modules should not be forced into this report. ## Report Definition Add a report definition under `internal/report`, preferably in a focused `near_term_report.go` file. Definition fields: - `ID`: `NearTerm` - `Name`: `Near-Term Report` - `PromptID`: `weather.near_term_report` - `ComparisonStrategy`: `rolling_window` - `ArtifactGroup`: `near-term` - `BatchOutputName`: `near-term.md` - `Generated`: `true` - `CompatiblePriorIDs`: `[]ID{NearTerm}` - `Modules`: near-term module list below - `resolve`: rolling near-term resolver Valid-period resolver: ```go func resolveNearTerm(req ResolveRequest) (timeutil.Period, error) { localNow := req.Now.In(req.Location) return timeutil.Period{ Start: localNow, End: localNow.Add(nearTermHours * time.Hour), }, nil } ``` The implementation should use idiomatic package-local constants and avoid duplicating duration literals in tests or app code. ## Default Module Composition Default module order should be: 1. `metadata` 2. `current_conditions` 3. `hourly_forecast` 4. `precip_timing` 5. `alert_digest` 6. `spc_convective_outlooks` 7. `area_forecast_discussion` 8. `spc_convective_discussion` 9. `weather_story` `area_forecast_discussion` should use options equivalent to: ```yaml sections: - key_messages - short_term ``` Do not include these daily/daypart-oriented modules initially: - `derived_daily_summary` - `derived_daypart_summaries` - `outdoor_windows` - `tomorrow_planning` If the report needs deterministic summary facts later, add a purpose-built module such as `derived_near_term_summary` rather than stretching daily modules into a rolling sub-daily context. ## Prompt Package Shape The existing prompt-input category layout should remain unchanged: - `applicable_risk_products` - `derived_summaries` - `narrative_products` - `raw_data` Near-term output is expected to emphasize: - `current_conditions` and `hourly_forecast` under `raw_data` - `precip_timing` under `derived_summaries` - `alert_digest` and `spc_convective_outlooks` under `applicable_risk_products` - `area_forecast_discussion`, `spc_convective_discussion`, and `weather_story` under `narrative_products` Module interval fields should use the existing prompt-facing `period_begins` / `period_ends` convention. ## Overlap And Filtering Rules Hourly forecast: - use only hourly periods overlapping the near-term valid period; - preserve hourly period order; - do not include the full daily forecast. Narrative products: - AFD key messages and short term text may be included because the AFD is an official short-term forecast discussion product; - narrative forecast periods are not included by default unless a later prompt test shows they improve near-term output. Alerts: - include active alert overlaps only when the alert overlaps the near-term valid period; - if alerts were checked successfully and no alerts overlap, emit checked empty alert context through existing module behavior. SPC outlooks: - include only retained outlooks whose valid periods overlap the near-term valid period; - do not include non-overlapping outlooks even if they are severe; - keep current prompt-facing field exclusions for geometry, severity rank, expiration time, and source URL. SPC discussion: - include discussion only for SPC days where a retained overlapping categorical outlook has severity rank at least `3`; - do not include discussion for low-risk, non-categorical-only, or non-overlapping outlooks. Weather story: - include when available under current optional-source behavior; - do not require the story valid period to exactly match the near-term period unless later testing shows stale stories are a problem. ## Implementation Stages ### Stage 1: Report Registry Goal: add the `near_term` report definition and valid-period resolver. Files to inspect or update: - `internal/report/definition.go` - `internal/report/registry.go` - `internal/report/period.go` - new `internal/report/near_term_report.go` - `internal/report/period_test.go` - `docs/internal/report-registry.md` after implementation Acceptance criteria: - `report.DefaultRegistry().Lookup(report.NearTerm)` succeeds. - `report.Registry.All()` includes the report in a stable order. - resolving the report at a fixed generation time produces a half-open six-hour period. - report metadata and RunID include `near_term`. ### Stage 2: Module Compatibility And Defaults Goal: allow existing relevant modules to build for `near_term` and define the default near-term composition. Files to inspect or update: - `internal/briefing/modules.go` - `internal/report/near_term_report.go` - `internal/briefing/*_module_test.go` - `internal/module/module_test.go` Acceptance criteria: - all default near-term modules validate and build from appropriate test facts; - daily-only modules remain incompatible unless intentionally expanded; - `area_forecast_discussion` defaults to key messages and short term only for this report. ### Stage 3: Derived Facts Goal: make `internal/facts` derive report-period facts for `near_term`. Files to inspect or update: - `internal/facts/facts.go` - `internal/facts/facts_test.go` - `internal/forecast` selection helpers, if needed Acceptance criteria: - valid-period hourly periods are sliced to the six-hour window; - precipitation timing is built from that six-hour hourly slice; - alert overlaps use the near-term valid period; - SPC outlook and discussion derivation use the near-term valid period; - no daily summaries or daypart summaries are required for the default near-term module set. ### Stage 4: CLI And App Wiring Goal: add explicit generation support without changing existing commands. Files to inspect or update: - `internal/app` - `internal/cli` - `cmd/weatherreporter/main.go` - `docs/cli.md` after implementation Expected command: ```bash weatherreporter generate near-term [--config PATH] [--units VALUE] [--tz NAME] [--out PATH] ``` Acceptance criteria: - command maps to `report.NearTerm`; - no `--date`, `--start`, or `--end` flags are added for this report; - existing `generate daily`, `generate tomorrow`, `generate three-day`, `generate weekend`, and `generate storm` behavior is unchanged; - CLI help lists the new command. ### Stage 5: Prompt Input And State Coverage Goal: prove the managed module snapshot and data package contain the intended near-term stanzas. Files to inspect or update: - `internal/app/app_test.go` - `internal/promptinput` - `internal/state` Acceptance criteria: - generated module snapshot includes the near-term default module list in order; - data package uses existing categories; - alert/SPC stanzas are omitted or checked-empty according to current module behavior and valid-period overlap; - report metadata preserves canonical `valid_period`; - module interval labels use `period_begins` and `period_ends`. ### Stage 6: Documentation And Examples Goal: document implemented behavior only after the code exists. Files to inspect or update after implementation: - `docs/cli.md` - `docs/internal/report-registry.md` - `docs/internal/module.md` - `docs/internal/facts.md` - `docs/internal/briefing.md` - `docs/config.md` only if report module overrides need an example update - `examples/config.yml` only if it lists report module overrides Acceptance criteria: - non-roadmap docs describe `near_term` only after implementation; - future or deferred near-term summary modules remain under roadmap docs; - examples, if updated, load through existing config tests. ## Test Plan Focused tests: ```bash go test ./internal/report ./internal/briefing ./internal/facts go test ./internal/app ./internal/cli ./internal/promptinput ``` Full validation: ```bash go test ./... go run ./cmd/weatherreporter --help git diff --check ``` Important coverage: - six-hour valid-period resolution from a fixed generation time; - timezone-aware period start and end; - no civil-day truncation; - hourly periods selected by overlap with the rolling window; - alert overlap filtering; - SPC outlook filtering by overlap; - SPC discussion filtering by overlap plus categorical severity threshold; - AFD key messages and short term included; - daily-only modules rejected or absent from default near-term composition; - distributor bundle path templates render sensibly for a sub-daily report, especially valid start time variables. ## Deferred Work Do not include these in the first implementation: - user-configurable near-term duration; - adding `near_term` to scheduled morning or evening batches; - a dedicated `derived_near_term_summary` module; - narrative forecast periods by default; - separate AFD section modules; - near-term-specific Recent Changes comparison output; - CLI flags for custom near-term duration. ## Open Questions None block the roadmap. Recommendation: implement the first version as explicit `generate near-term` only, with no scheduled batch membership. That keeps the user-visible behavior small while the prompt and generated report are tested. Viable alternative: add `near_term` to a frequent scheduled batch immediately. That may be useful operationally, but it should wait until the report cadence and downstream distributor behavior are clear.