# Tomorrow Report Roadmap ## Purpose This roadmap defines the target state for making Tomorrow an independent generated-text-template report. The feature is not implemented yet, so this document lives under `docs/roadmap/`. ## Intent Tomorrow should become its own report product, not a variant of the Daily Report. The current CLI command `weatherreporter generate tomorrow` should remain, but the internal report ID, prompt ID, template, schema, workspace paths, and distributor identity should use `tomorrow`. The report should combine deterministic daypart and precipitation facts with LLM prose for the high-level summary, optional precipitation context, and forecast discussion. The resulting Markdown should be predictable and template-driven, similar to the implemented Hourly Report. Longer term, Today, Tomorrow, and Daily may all become separate report products with different prompts, templates, and deterministic sections. This roadmap starts that split with Tomorrow. ## Target Report Shape Example structure: ```markdown # Sunday's Weather **Forecast Date:** Sunday, June 15, 2026 **Generated:** Saturday, June 14, 2026 at 9:14 AM ## Daypart Forecast - **Overnight:** - **Morning:** - **Midday:** - **Afternoon:** - **Evening:** ## Precipitation Timing - **1:00 AM** to **5:00 AM**: Precipitation is expected during this period. The peak precipitation chance is 59% at 2:00 AM. - ## Forecast Discussion ``` `Precipitation Timing` should render only when at least one precipitation window exists for the valid period. The threshold for precipitation windows remains the existing precipitation-window threshold, currently 40%. ## Locked Decisions - Replace report ID `daily_tomorrow` with `tomorrow`. - Do not preserve compatibility aliases for `daily_tomorrow`; this is a pre-release clean break. - Keep public CLI syntax: `weatherreporter generate tomorrow`. - Use generated-text-template generation for Tomorrow, not full Markdown generation by Scriptorium. - Use a dedicated Scriptorium prompt ID, template ID, and schema ID: - prompt ID: `weather.tomorrow_generated_text` - template ID: `tomorrow` - generated-text schema ID: `tomorrow` - Use `ArtifactGroup: "tomorrow"` and `BatchOutputName: "tomorrow.md"`. - Use `CompatiblePriorIDs: []report.ID{report.Tomorrow}`. - Keep valid-period behavior: Tomorrow covers the next local civil day. - Keep Morning/Evening batch behavior unless explicitly changed later; evening batch should still include Tomorrow. - Future Today/Daily split is out of scope for this roadmap. ## GeneratedText Contract Add a Tomorrow GeneratedText schema: ```json { "summary": "string", "forecast_discussion": ["string"], "precipitation_timing": "string", "confidence": "string" } ``` Required: - `summary` - `forecast_discussion` Optional: - `precipitation_timing` - `confidence` `forecast_discussion` should be an array of paragraph strings so Scriptorium can return multi-paragraph discussion without embedding paragraph delimiters in one string. Empty or whitespace-only discussion paragraphs should be rejected or trimmed out during validation; after trimming, at least one paragraph is required. `confidence` may be validated and persisted but does not need to render in the initial template. ## Template Context Add a dedicated Tomorrow render context rather than reusing Hourly context types. Recommended top-level shape: ```go type TomorrowRenderContext struct { Report TomorrowReportContext GeneratedText Tomorrow Modules TomorrowTemplateModules Collected facts.CollectedFacts Derived facts.DerivedFacts } ``` `TomorrowReportContext` should include: - `Title`: for example `Sunday's Weather` - `ForecastDate`: canonical local forecast date if useful - `ForecastDateLabel`: for example `Sunday, June 15, 2026` - `ForecastDayName`: for example `Sunday` - `GeneratedAt` - `GeneratedAtLabel`: for example `Saturday, June 14, 2026 at 9:14 AM` - `ValidPeriod` - `Timezone` Do not derive the possessive title in the template. Go should provide `Title` so wording is consistent and easy to test. `TomorrowTemplateModules` should expose the module outputs needed by the template: - `Metadata` - `DerivedDailySummary` - `DerivedDaypartSummaries` - `PrecipTiming` - `AlertDigest` - `SPCConvectiveOutlooks` - `AreaForecastDiscussion` - `SPCConvectiveDiscussion` - `WeatherStory` - `TomorrowPlanning`, if still useful Current conditions and hourly forecast can remain in the module snapshot and data package if useful for Scriptorium, but they do not need to render in the initial Tomorrow template unless a later design calls for them. ## Daypart Forecast The Daypart Forecast should be deterministic but composable. Avoid adding a single prewritten Go `DaypartLine` string that makes template wording rigid. Add presentation-friendly fields to `derived_daypart_summaries` only where they avoid awkward template logic. Likely useful fields: - display name, such as `Overnight` or `Morning`; - lower-case dominant condition text for inline sentences; - rounded temperature range phrase if available; - precipitation mention flag using the existing hourly line mention threshold concept, currently 20%; - max precipitation probability and friendly max time; - optional wind phrase or wind range only if deterministic wind wording is clearly needed. The initial implementation may keep daypart bullet wording simple. It should be easy to revise the template text without editing Go unless new facts are needed. ## Implementation Plan 1. Report identity split - Rename `report.DailyTomorrow` to `report.Tomorrow` with ID `tomorrow`. - Update registry order, resolver references, CLI mapping, batch selection, state metadata expectations, docs, and tests. - Preserve `weatherreporter generate tomorrow`. - Accept that workspace paths, RunIDs, distributor bundle IDs, and report URLs change from `daily_tomorrow` to `tomorrow`. 2. GeneratedText contract - Add `generatedtext.Tomorrow`, validation, normalized JSON output, and tests. - Add `tomorrow.generated_text.schema.json`. - Add `internal/reporttemplate/prompts/tomorrow.generated_text.md` as the maintained prompt source asset. - Update app validation dispatch to use the Tomorrow schema. 3. Template and render context - Add `internal/reporttemplate/templates/tomorrow.md.tmpl`. - Add Tomorrow template/schema lookup entries. - Add `BuildTomorrowRenderContext`. - Update app render-context dispatch for template ID `tomorrow`. - Persist render context in the existing generated-text-template workflow. 4. Module presentation fields - Add only the daypart presentation fields needed by the template. - Reuse the existing precipitation window hour-label fields. - Keep deterministic weather derivation in Go and wording/layout in the template. 5. Report definition conversion - Change Tomorrow report definition to: - `PromptID: "weather.tomorrow_generated_text"` - `GenerationMode: generated_text_template` - `TemplateID: "tomorrow"` - `GeneratedTextSchemaID: "tomorrow"` - `ArtifactGroup: "tomorrow"` - `BatchOutputName: "tomorrow.md"` - compatible prior IDs containing only `tomorrow` - Review module composition and keep only modules used by the prompt, template, or future inspection value. 6. Documentation and examples - After implementation, update non-roadmap docs for implemented behavior: `docs/cli.md`, `docs/operations.md`, `docs/internal/report-registry.md`, `docs/internal/generatedtext.md`, `docs/internal/reporttemplate.md`, and `docs/templates.md`. - Update examples that refer to `reports.tomorrow` or report module overrides if the config key changes. ## Test Plan - Report tests: - registry contains `tomorrow`, not `daily_tomorrow`; - `generate tomorrow` resolves report ID `tomorrow`; - valid period remains next local civil day; - evening batch still includes Tomorrow; - RunID and artifact paths use `tomorrow`. - GeneratedText tests: - `summary` and non-empty `forecast_discussion` are required; - `forecast_discussion` trims paragraph strings and rejects/omits blanks; - optional `precipitation_timing` and `confidence` normalize correctly; - unknown fields are rejected. - Template tests: - title renders as `'s Weather`; - forecast date and generated labels render; - daypart bullets render in configured daypart order; - precipitation section is omitted when no precipitation windows exist; - precipitation section includes deterministic windows and optional LLM text when windows exist; - forecast discussion renders multiple paragraphs. - App/CLI workflow tests: - `weatherreporter generate tomorrow` uses structured Scriptorium output and the template renderer; - raw generated text, validated generated text, render context, report, and metadata artifacts are persisted; - optional `--out` behavior remains unchanged; - distributor notification uses report ID/artifact group `tomorrow`. Validation commands: ```bash go test ./internal/report ./internal/generatedtext ./internal/reporttemplate ./internal/briefing ./internal/app ./internal/cli ./internal/state go test ./... go run ./cmd/weatherreporter --help git diff --check ``` ## Open Questions None block implementation. Recommended defaults are: - make `forecast_discussion` an array of strings for Tomorrow; - keep Hourly GeneratedText unchanged for now; - do not add Daily Today or generic Daily report splits in this change; - do not preserve `daily_tomorrow` compatibility aliases.