Files
weatherreporter/docs/roadmap/today.md

15 KiB

Today Report Roadmap

Purpose

This roadmap defines the target state and implementation work needed to add a new independent generated-text-template today report.

The report is not implemented yet. Current report behavior remains documented outside docs/roadmap/.

Intent

Today should be an independent generated-text-template report focused on the current local civil day. It should mirror the implemented Tomorrow Report structure, but its valid period, identity, prompt, template, schema, workspace paths, distributor identity, and deterministic planning module should use today.

This is a clean, separate report addition:

  • today becomes a new canonical current-day generated-text report ID.
  • The existing daily_today report remains independent for now.
  • The existing public daily command remains independent for now.
  • weatherreporter generate today and weatherreporter generate daily must not be aliases for each other.
  • Morning batch should use today, not daily_today.
  • New Today artifacts use the today artifact group and report ID.
  • Existing historical daily_today workspace artifacts do not need migration.

The next planned feature will rewrite the daily command/report in the same style as Today and Tomorrow. Do not pre-solve that future work in this roadmap.

Locked Decisions

  • today is independent of daily_today.
  • generate today is independent of generate daily.
  • No command compatibility aliases between today and daily.
  • No config-key compatibility aliases between reports.today and reports.daily / reports.daily_today.
  • Morning batch includes today.
  • Morning batch should not include daily_today once Today is implemented.
  • today needs its own deterministic planning module analogous to TomorrowPlanning.
  • Add a new public generate today command.
  • Do not reuse the Tomorrow prompt, template, schema, report ID, artifact group, or planning stanza for Today.
  • Do not attempt to migrate old workspace artifacts.

Target Report Shape

Today should render from deterministic current-day facts plus structured prose from Scriptorium:

# Today's Weather

**Forecast date:** Friday, May 29, 2026
**Updated:** Friday, May 29, 2026 at 8:30 AM

<GeneratedText summary>

## Daypart Forecast

- **Morning:** <deterministic daypart line>
- **Midday:** <deterministic daypart line>
- **Afternoon:** <deterministic daypart line>
- **Evening:** <deterministic daypart line>

## Precipitation Timing

- **10:00 AM** to **1:00 PM**: Precipitation is expected during this period.
  The peak precipitation chance is 70% at 11:00 AM.
- <optional GeneratedText precipitation_timing>

## Forecast Discussion

<GeneratedText forecast_discussion paragraphs>

The precipitation section should render only when precipitation windows exist for the current-day valid period. The deterministic daypart forecast should follow the same module-driven presentation approach used by Tomorrow.

The title should be stable and explicit: Today's Weather.

Report Identity

Add a report definition with:

  • report ID: today
  • public generate command: today
  • prompt ID: weather.today_generated_text
  • generation mode: generated_text_template
  • template ID: today
  • generated-text schema ID: today
  • artifact group: today
  • batch output name: today.md
  • prior compatibility: Today only
  • comparison strategy: same valid local date
  • valid period: current local civil day in the effective report timezone, [00:00, next 00:00)

Keep the existing daily_today report definition independent unless the future Daily rewrite roadmap removes or replaces it.

Command and config resolution must remain distinct:

  • generate today resolves to report ID today.
  • generate daily resolves to the existing daily report ID.
  • reports.today config overrides apply only to report ID today.
  • reports.daily and reports.daily_today config overrides continue to apply only to the existing daily report while that report exists.

Batch Behavior

Morning batch should include Today in the position currently occupied by Daily Today.

Target morning order:

  1. today
  2. three_day
  3. weekend, when existing weekend rules include it

Existing Sunday behavior should remain equivalent except with Today replacing Daily Today in the batch: scheduled Sunday morning should include today and three_day, and should skip weekend.

Evening batch behavior is unchanged and should continue to include tomorrow. Hourly remains excluded from scheduled batches unless a later roadmap changes that.

The existing daily command/report may remain available for manual generation, but it is no longer the morning batch current-day product once Today is implemented.

GeneratedText Contract

Today 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 for the source prompt text if prompt assets are maintained locally:

  • internal/reporttemplate/prompts/today.generated_text.md

Scriptorium registration remains out of band. Weatherreporter should invoke the Today prompt by prompt ID and pass the data package as it does for other generated-text reports.

Template Context

Add dedicated Today types under internal/generatedtext, rather than reusing Tomorrow types directly. The shape should mirror Tomorrow so template behavior stays explicit and testable:

type TodayRenderContext struct {
    Report        TodayReportContext
    GeneratedText Today
    Modules       TodayTemplateModules
    Collected     facts.CollectedFacts
    Derived       facts.DerivedFacts
}

TodayReportContext should include:

  • Title, exactly Today's Weather
  • ForecastDate
  • ForecastDateLabel, for example Friday, May 29, 2026
  • ForecastDayName, for example Friday
  • GeneratedAt
  • GeneratedAtLabel
  • ValidPeriod
  • Timezone

TodayTemplateModules should expose the categories the Today template needs:

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

Today may share private helper functions with Tomorrow render-context construction when the helper represents identical mechanics, such as snapshot lookup or daypart row ordering. Do not expose Tomorrow-specific types through the Today template context.

Module Composition

The default module composition should mirror Tomorrow where the same facts are useful for the current-day report, with a Today-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
  • hourly_forecast
  • today_planning

Keep module outputs deterministic and prompt-facing. Do not add prose-only Go fields unless the template needs a structured fact that cannot be expressed from existing module data.

Today Planning Module

Add a Today-specific deterministic planning module:

  • module ID: today_planning
  • stanza name: today_planning
  • options type: TodayPlanningOptions
  • output type: TodayPlanningModule
  • supported report: today

The module should be analogous to TomorrowPlanning, but current-day oriented. It should not reuse the public TomorrowPlanningModule type or tomorrow_planning stanza.

Recommended initial fields:

  • morning_readiness
  • commute_school_workday_concerns
  • outdoor_planning
  • late_day_change_watch

The exact field names may be adjusted during implementation if tests and docs make a better shape clear, but the module must remain deterministic and current-day specific. Private helper functions may be shared with Tomorrow planning when the underlying logic is truly identical.

Implementation Plan

  1. Add Today report identity.

    • Add report.Today.
    • Keep the existing report.DailyToday active for now.
    • Add command-name support for today.
    • Do not change the daily command mapping in this roadmap.
    • Add config-key support for today.
    • Do not change reports.daily or reports.daily_today mapping in this roadmap.
    • Add a report definition with generated-text-template identity fields.
    • Add current-local-civil-day valid-period resolution.
    • Update report tests for ID, prompt ID, artifact group, command mapping, config key mapping, batch order, and valid period.
  2. Add Today planning module.

    • Add module.TodayPlanning.
    • Add TodayPlanningOptions.
    • Add TodayPlanningModule and builder under internal/briefing.
    • Register it in the default module registry for report.Today.
    • Add tests for output shape, supported report, unsupported reports, and empty/fallback behavior.
  3. Add Today generated-text validation and schema.

    • Add generatedtext.Today.
    • Add ValidateToday.
    • Add today.generated_text.schema.json.
    • Add generated-text validation tests matching Tomorrow coverage.
  4. Add Today template and render context.

    • Add today.md.tmpl.
    • Add TodayRenderContext, TodayReportContext, and TodayTemplateModules.
    • Add BuildTodayRenderContext.
    • Use the internal snapshot lookup helper for module extraction.
    • Add render-context and template tests for populated and omitted optional modules.
  5. Register Today in generated-text and embedded asset catalogs.

    • Add a generated-text catalog entry.
    • Add reporttemplate template/schema map entries if the current asset lookup still uses explicit maps.
    • Extend catalog completeness tests.
    • Add unsupported schema/template combination coverage if needed.
  6. Integrate app, CLI, config, batches, and distributor workflows.

    • Ensure weatherreporter generate today resolves and runs through the generated-text-template workflow.
    • Ensure weatherreporter generate daily remains the existing daily workflow and does not resolve to Today.
    • Ensure morning batch uses today instead of daily_today.
    • Persist raw generated text, structured run result, normalized generated text, render context, Markdown report, metadata, and optional output copy.
    • Ensure distributor notification uses the managed Today Markdown report path and Today template values.
    • Ensure report metadata, RunID, artifact paths, data-package paths, batch output names, and distributor template variables use today.
  7. Update implemented documentation after code changes.

    • Update docs/cli.md, docs/config.md, docs/operations.md, docs/templates.md, docs/internal/report-registry.md, docs/internal/generatedtext.md, docs/internal/reporttemplate.md, docs/internal/module.md, docs/internal/app-orchestration.md, and maintained examples as needed.
    • Non-roadmap docs must describe only the implemented Today behavior after the code changes land.
    • Keep daily and today documented as distinct commands/reports.

Test Plan

Add or update tests for:

  • report registry membership for both today and existing daily_today
  • today command-name resolution to today
  • daily command-name resolution remaining independent from today
  • config-key resolution for reports.today
  • config-key resolution for reports.daily and reports.daily_today remaining independent from reports.today
  • morning batch order with today, three_day, and conditional weekend
  • Sunday morning batch skip behavior with today
  • current-day valid period in the configured timezone
  • generated-text unknown fields, trailing JSON, missing required fields, blank fields, paragraph trimming, and canonical output
  • generated-text catalog completeness
  • template/schema asset lookup
  • render context labels, module extraction, nil optional modules, Today planning extraction, and daypart ordering
  • Today planning module output and supported-report validation
  • app workflow artifacts for generate today
  • generate daily remains separate from generate today
  • optional --out copy behavior
  • distributor template values and managed report notification source
  • CLI parser support for generate today
  • config report module overrides for reports.today

Suggested validation:

go test ./internal/report ./internal/generatedtext ./internal/reporttemplate
go test ./internal/briefing ./internal/module
go test ./internal/app ./internal/cli ./internal/config
go test ./...
go run ./cmd/weatherreporter --help
git diff --check

Documentation Updates After Implementation

Update implemented docs only after the code exists:

  • docs/cli.md: document generate today and keep generate daily documented as a separate existing command.
  • docs/config.md: document reports.today module overrides separately from existing daily report overrides.
  • docs/operations.md: document Today artifact paths, morning batch behavior, and distributor upload identity.
  • docs/templates.md: document Today template variables.
  • docs/internal/report-registry.md: document Today report identity and its independence from Daily Today.
  • docs/internal/generatedtext.md: document Today generated-text schema and validation behavior.
  • docs/internal/reporttemplate.md: document Today template assets.
  • docs/internal/module.md: document today_planning.
  • docs/internal/app-orchestration.md: document Today workflow only if it differs from the generic generated-text-template flow.

Ambiguities Addressed

  • Independence: today is separate from daily_today; it does not replace the existing report definition in this roadmap.
  • Command behavior: generate today and generate daily are not aliases.
  • Config behavior: reports.today is not an alias for reports.daily or reports.daily_today.
  • Batch behavior: morning batch includes today instead of daily_today.
  • Planning module: Today has its own deterministic planning module.
  • Artifact identity: new Today artifacts and distributor values use today.
  • 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:

  • How the future rewritten daily command/report should relate to today.
  • Whether the future Daily rewrite removes or retires daily_today.
  • Whether old daily_today workspace artifacts should ever receive a migration or inspection compatibility layer.