11 KiB
Daily Report Roadmap
Purpose
This roadmap defines the target state and policy choices for replacing the
existing daily report with a new generated-text-template daily report.
The new report is not implemented yet. Current report behavior remains
documented outside docs/roadmap/.
Intent
Daily should be an independent generated-text-template report for a user-chosen local civil day. Its rendered Markdown should initially match the Tomorrow Report format exactly, but its identity, prompt, template, schema, valid-period resolver, config key, and planning module should be separate from Tomorrow from the start.
The important distinction is date selection:
tomorrowalways targets the next local civil day.dailytargets the local civil day explicitly supplied by the user with--date YYYY-MM-DD.
This is a clean breaking replacement of the current Daily implementation:
- The existing direct-Markdown
dailyreport is removed. - The legacy
daily_todayreport ID is removed from active report definitions. weatherreporter generate dailyremains the public command name, but it now runs the new generated-text-template Daily report.weatherreporter generate dailyrequires--date YYYY-MM-DD.- Existing historical
daily_todayworkspace artifacts do not need migration.
Locked Decisions
- New report ID:
daily. - Public command:
generate daily. generate dailymust require--date YYYY-MM-DD.- The provided date is interpreted as a civil date in the effective report timezone.
- The valid period is the selected local civil day,
[00:00, next 00:00). - Daily should not be an alias for Today or Tomorrow.
- Today remains the current-day scheduled morning product.
- Tomorrow remains the next-day scheduled evening product.
- Daily is manually targeted by date and is not added to morning or evening batch membership in this roadmap.
- Daily must have its own template, generated-text schema, prompt asset, render-context type, and planning module.
- Daily may share private helper functions with Tomorrow where mechanics are identical, but it must not expose Tomorrow-specific public types or stanzas.
- The initial Daily output format should match Tomorrow's rendered Markdown format.
Target Report Shape
Daily should render the same Markdown structure as Tomorrow:
# Monday's Weather
**Forecast date:** Monday, June 15, 2026
**Updated:** Sunday, June 14, 2026 at 9:14 AM
<GeneratedText summary>
## Daypart Forecast
- **Morning:** <deterministic daypart line>
- **Midday:** <deterministic daypart line>
- **Afternoon:** <deterministic daypart line>
- **Evening:** <deterministic daypart line>
## Precipitation Timing
- **1:00 PM** to **5:00 PM**: Precipitation is expected during this period.
The peak precipitation chance is 59% at 2:00 PM.
- <optional GeneratedText precipitation_timing>
## Forecast Discussion
<GeneratedText forecast_discussion paragraphs>
The precipitation section should render only when precipitation windows exist for the selected valid period.
The title should follow Tomorrow's day-name style, for example:
Monday's WeatherTuesday's WeatherSunday's Weather
Report Identity
Replace the existing active Daily report with:
- report ID:
daily - public generate command:
daily - prompt ID:
weather.daily_generated_text - generation mode:
generated_text_template - template ID:
daily - generated-text schema ID:
daily - artifact group:
daily - batch output name:
daily.md - prior compatibility: Daily only
- comparison strategy: same valid local date
- valid period: selected local civil day in the effective report timezone,
[00:00, next 00:00)
Remove the legacy active report identity:
- remove active report ID
daily_today - remove prompt ID
weather.daily_reportfrom the current Daily path - remove direct-Markdown generation mode from the Daily report definition
- remove
daily_todayconfig-key support unless a separate migration roadmap explicitly reintroduces it
Historical artifacts with daily_today metadata may remain on disk. Do not
migrate or rewrite old workspace files in this feature.
CLI Behavior
weatherreporter generate daily should require:
weatherreporter generate daily --date YYYY-MM-DD
Rules:
--dateis required forgenerate daily.--dateaccepts onlyYYYY-MM-DD.- The date is interpreted in the effective report timezone after config and
--tzoverrides are applied. - Omitting
--dateis an error. - A malformed date is an error.
- The command should continue supporting the existing global generation flags:
--config,--units,--tz, and--out. - Do not default
dailyto today or tomorrow.
Batch Behavior
Daily should not be added to scheduled batches in this roadmap.
Current intended scheduled behavior:
- Morning batch:
today,three_day, and conditionalweekend. - Evening batch:
tomorrow.
Daily is a manually targeted report. A future roadmap may add scheduled Daily behavior if a concrete operational need appears.
GeneratedText Contract
Daily should use the same structured prose shape as Tomorrow:
{
"summary": "string",
"forecast_discussion": ["string"],
"precipitation_timing": "string",
"confidence": "string"
}
Required:
summaryforecast_discussion
Optional:
precipitation_timingconfidence
Validation should match Tomorrow semantics:
- reject malformed JSON and unknown fields
- reject trailing JSON values
- trim
summary,precipitation_timing, andconfidence - trim each
forecast_discussionparagraph - drop blank discussion paragraphs
- require at least one nonblank discussion paragraph
- return canonical normalized JSON with the same public field names
Add a dedicated prompt asset:
internal/reporttemplate/prompts/daily.generated_text.md
Scriptorium registration remains out of band. Weatherreporter should invoke the Daily prompt by prompt ID and pass the data package as it does for other generated-text reports.
Template Context
Add dedicated Daily types under internal/generatedtext, rather than reusing
Tomorrow types directly:
type DailyRenderContext struct {
Report DailyReportContext
GeneratedText Daily
Modules DailyTemplateModules
Collected facts.CollectedFacts
Derived facts.DerivedFacts
}
DailyReportContext should include:
Title, for exampleMonday's WeatherForecastDateForecastDateLabel, for exampleMonday, June 15, 2026ForecastDayName, for exampleMondayGeneratedAtGeneratedAtLabelValidPeriodTimezone
DailyTemplateModules should expose the same categories the Daily template
needs:
MetadataCurrentConditionsHourlyForecastDerivedDailySummaryDerivedDaypartSummaries- ordered daypart rows
PrecipTimingAlertDigestSPCConvectiveOutlooksAreaForecastDiscussionSPCConvectiveDiscussionWeatherStoryOutdoorWindowsDailyPlanning
Daily may share private helper functions with Tomorrow render-context construction when the helper represents identical mechanics. Do not expose Tomorrow-specific types through the Daily template context.
Module Composition
The default module composition should initially mirror Tomorrow where the same facts are useful for a dated daily report, with a Daily-specific planning module:
metadatacurrent_conditionsnarrative_forecastderived_daily_summaryderived_daypart_summariesprecip_timingalert_digestspc_convective_outlooksarea_forecast_discussionspc_convective_discussionweather_storyoutdoor_windowsdaily_planninghourly_forecast
The module order should match the intended data-package order unless tests show a stronger reason to mirror Tomorrow's exact current order.
Daily Planning Module
Add a Daily-specific deterministic planning module:
- module ID:
daily_planning - stanza name:
daily_planning - options type:
DailyPlanningOptions - output type:
DailyPlanningModule - supported report:
daily
The module should be initially equivalent to TomorrowPlanning, but independent
from it:
- do not reuse the public
TomorrowPlanningModuletype - do not emit the
tomorrow_planningstanza - do not use
module.TomorrowPlanningin the Daily default composition
Recommended initial fields should match Tomorrow planning:
morning_readinesscommute_school_workday_concernsovernight_change_watch
Private helper functions may be shared with Tomorrow planning when the underlying logic is truly identical.
Acceptance Criteria
The feature is complete when:
weatherreporter generate daily --date YYYY-MM-DDruns the new Daily report.weatherreporter generate dailywithout--datefails with an actionable error.dailyreport metadata, RunID content, artifact paths, data-package paths, distributor template variables, generated-text assets, and rendered Markdown all use report IDdaily.- The active report registry includes
dailyand does not includedaily_today. reports.dailyis the implemented config override key for Daily.reports.daily_todayis rejected rather than treated as an alias.- Daily uses generated-text-template generation with prompt ID
weather.daily_generated_text. - Daily uses dedicated schema, prompt, template, generated-text type, render-context type, and planning-module surfaces.
- Daily rendered Markdown initially matches Tomorrow's report format.
- Daily data packages include
daily_planning, nottomorrow_planning. - Daily Recent Changes compare against prior Daily snapshots for the same valid local date.
- Daily is not included in morning or evening scheduled batches.
- Existing Today and Tomorrow report semantics remain unchanged.
- Historical
daily_todayworkspace artifacts are left untouched. - Non-roadmap documentation is updated after implementation to describe only implemented Daily behavior.
Implementation Plan Reference
Use docs/roadmap/implementation.md for the staged implementation plan. This
feature roadmap intentionally does not define implementation stages, file-by-file
work packages, or validation commands so that implementing agents have a single
sequencing authority.
Ambiguities Addressed
- Replacement scope: new
dailyreplaces and removes old activedaily_today. - Date behavior:
--dateis required; no default date is used. - Output format: initial rendered Markdown matches Tomorrow.
- Internal separation: Daily has its own template, schema, prompt, generated text type, render context, and planning module.
- Batch behavior: Daily is not scheduled; Today remains the morning current-day scheduled product.
- Historical artifacts: old
daily_todayworkspace files are not migrated.
Open Decisions
No open decisions remain that block implementation.
Future decisions that should not be resolved in this roadmap:
- Whether Daily should eventually support recurring scheduled generation.
- Whether Daily should diverge from Tomorrow's template or planning logic.
- Whether old
daily_todayworkspace artifacts should ever receive a migration or inspection compatibility layer.