9.7 KiB
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:
# Sunday's Weather
**Forecast Date:** Sunday, June 15, 2026
**Generated:** Saturday, June 14, 2026 at 9:14 AM
<GeneratedText summary>
## Daypart Forecast
- **Overnight:** <deterministic daypart line>
- **Morning:** <deterministic daypart line>
- **Midday:** <deterministic daypart line>
- **Afternoon:** <deterministic daypart line>
- **Evening:** <deterministic daypart line>
## 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.
- <optional GeneratedText precipitation_timing>
## Forecast Discussion
<GeneratedText forecast_discussion paragraphs>
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_tomorrowwithtomorrow. - 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
- prompt ID:
- Use
ArtifactGroup: "tomorrow"andBatchOutputName: "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:
{
"summary": "string",
"forecast_discussion": ["string"],
"precipitation_timing": "string",
"confidence": "string"
}
Required:
summaryforecast_discussion
Optional:
precipitation_timingconfidence
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:
type TomorrowRenderContext struct {
Report TomorrowReportContext
GeneratedText Tomorrow
Modules TomorrowTemplateModules
Collected facts.CollectedFacts
Derived facts.DerivedFacts
}
TomorrowReportContext should include:
Title: for exampleSunday's WeatherForecastDate: canonical local forecast date if usefulForecastDateLabel: for exampleSunday, June 15, 2026ForecastDayName: for exampleSundayGeneratedAtGeneratedAtLabel: for exampleSaturday, June 14, 2026 at 9:14 AMValidPeriodTimezone
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:
MetadataDerivedDailySummaryDerivedDaypartSummariesPrecipTimingAlertDigestSPCConvectiveOutlooksAreaForecastDiscussionSPCConvectiveDiscussionWeatherStoryTomorrowPlanning, 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
OvernightorMorning; - 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
-
Report identity split
- Rename
report.DailyTomorrowtoreport.Tomorrowwith IDtomorrow. - 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_tomorrowtotomorrow.
- Rename
-
GeneratedText contract
- Add
generatedtext.Tomorrow, validation, normalized JSON output, and tests. - Add
tomorrow.generated_text.schema.json. - Add
internal/reporttemplate/prompts/tomorrow.generated_text.mdas the maintained prompt source asset. - Update app validation dispatch to use the Tomorrow schema.
- Add
-
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.
- Add
-
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.
-
Report definition conversion
- Change Tomorrow report definition to:
PromptID: "weather.tomorrow_generated_text"GenerationMode: generated_text_templateTemplateID: "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.
- Change Tomorrow report definition to:
-
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, anddocs/templates.md. - Update examples that refer to
reports.tomorrowor report module overrides if the config key changes.
- After implementation, update non-roadmap docs for implemented behavior:
Test Plan
- Report tests:
- registry contains
tomorrow, notdaily_tomorrow; generate tomorrowresolves report IDtomorrow;- valid period remains next local civil day;
- evening batch still includes Tomorrow;
- RunID and artifact paths use
tomorrow.
- registry contains
- GeneratedText tests:
summaryand non-emptyforecast_discussionare required;forecast_discussiontrims paragraph strings and rejects/omits blanks;- optional
precipitation_timingandconfidencenormalize correctly; - unknown fields are rejected.
- Template tests:
- title renders as
<weekday>'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.
- title renders as
- App/CLI workflow tests:
weatherreporter generate tomorrowuses structured Scriptorium output and the template renderer;- raw generated text, validated generated text, render context, report, and metadata artifacts are persisted;
- optional
--outbehavior remains unchanged; - distributor notification uses report ID/artifact group
tomorrow.
Validation commands:
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_discussionan 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_tomorrowcompatibility aliases.