Files
weatherreporter/docs/roadmap/daily.md

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:

  • tomorrow always targets the next local civil day.
  • daily targets 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 daily report is removed.
  • The legacy daily_today report ID is removed from active report definitions.
  • weatherreporter generate daily remains the public command name, but it now runs the new generated-text-template Daily report.
  • weatherreporter generate daily requires --date YYYY-MM-DD.
  • Existing historical daily_today workspace artifacts do not need migration.

Locked Decisions

  • New report ID: daily.
  • Public command: generate daily.
  • generate daily must 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 Weather
  • Tuesday's Weather
  • Sunday'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_report from the current Daily path
  • remove direct-Markdown generation mode from the Daily report definition
  • remove daily_today config-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:

  • --date is required for generate daily.
  • --date accepts only YYYY-MM-DD.
  • The date is interpreted in the effective report timezone after config and --tz overrides are applied.
  • Omitting --date is 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 daily to 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 conditional weekend.
  • 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:

  • summary
  • forecast_discussion

Optional:

  • precipitation_timing
  • confidence

Validation should match Tomorrow semantics:

  • reject malformed JSON and unknown fields
  • reject trailing JSON values
  • trim summary, precipitation_timing, and confidence
  • trim each forecast_discussion paragraph
  • 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 example Monday's Weather
  • ForecastDate
  • ForecastDateLabel, for example Monday, June 15, 2026
  • ForecastDayName, for example Monday
  • GeneratedAt
  • GeneratedAtLabel
  • ValidPeriod
  • Timezone

DailyTemplateModules should expose the same categories the Daily template needs:

  • Metadata
  • CurrentConditions
  • HourlyForecast
  • DerivedDailySummary
  • DerivedDaypartSummaries
  • ordered daypart rows
  • PrecipTiming
  • AlertDigest
  • SPCConvectiveOutlooks
  • AreaForecastDiscussion
  • SPCConvectiveDiscussion
  • WeatherStory
  • OutdoorWindows
  • DailyPlanning

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:

  • metadata
  • current_conditions
  • narrative_forecast
  • derived_daily_summary
  • derived_daypart_summaries
  • precip_timing
  • alert_digest
  • spc_convective_outlooks
  • area_forecast_discussion
  • spc_convective_discussion
  • weather_story
  • outdoor_windows
  • daily_planning
  • hourly_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 TomorrowPlanningModule type
  • do not emit the tomorrow_planning stanza
  • do not use module.TomorrowPlanning in the Daily default composition

Recommended initial fields should match Tomorrow planning:

  • morning_readiness
  • commute_school_workday_concerns
  • overnight_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-DD runs the new Daily report.
  • weatherreporter generate daily without --date fails with an actionable error.
  • daily report metadata, RunID content, artifact paths, data-package paths, distributor template variables, generated-text assets, and rendered Markdown all use report ID daily.
  • The active report registry includes daily and does not include daily_today.
  • reports.daily is the implemented config override key for Daily.
  • reports.daily_today is 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, not tomorrow_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_today workspace 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 daily replaces and removes old active daily_today.
  • Date behavior: --date is 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_today workspace 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_today workspace artifacts should ever receive a migration or inspection compatibility layer.