262 lines
8.2 KiB
Markdown
262 lines
8.2 KiB
Markdown
# Today Report Roadmap
|
|
|
|
## Purpose
|
|
|
|
This roadmap defines the work needed to add a new `today` report type. The
|
|
report is not implemented. Current report behavior is 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, and distributor identity should use `today`.
|
|
|
|
Today should not replace the existing Daily Today report in the same change.
|
|
Daily Today currently remains the direct-Markdown `daily` command and report ID
|
|
`daily_today`. The Today report should be added as a separate product so the
|
|
project can compare the generated-text-template version with the existing
|
|
direct-Markdown daily report before deciding whether to retire or rename either
|
|
one.
|
|
|
|
## Target Report Shape
|
|
|
|
Today should render from deterministic current-day facts plus structured prose
|
|
from Scriptorium:
|
|
|
|
```markdown
|
|
# 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.
|
|
|
|
## 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 Report only
|
|
- comparison strategy: same valid date
|
|
- valid period: current local civil day in the effective report timezone
|
|
|
|
Do not change existing `daily`, `daily_today`, or morning batch behavior in the
|
|
same implementation unless a separate roadmap explicitly calls for that change.
|
|
|
|
## GeneratedText Contract
|
|
|
|
Today should use the same structured prose shape as Tomorrow:
|
|
|
|
```json
|
|
{
|
|
"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
|
|
|
|
## 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:
|
|
|
|
```go
|
|
type TodayRenderContext struct {
|
|
Report TodayReportContext
|
|
GeneratedText Today
|
|
Modules TodayTemplateModules
|
|
Collected facts.CollectedFacts
|
|
Derived facts.DerivedFacts
|
|
}
|
|
```
|
|
|
|
`TodayReportContext` should include:
|
|
|
|
- `Title`, for example `Today's Weather`
|
|
- `ForecastDate`
|
|
- `ForecastDateLabel`, for example `Friday, May 29, 2026`
|
|
- `ForecastDayName`, for example `Friday`
|
|
- `GeneratedAt`
|
|
- `GeneratedAtLabel`
|
|
- `ValidPeriod`
|
|
- `Timezone`
|
|
|
|
`TodayTemplateModules` should expose the same categories the Today template
|
|
needs:
|
|
|
|
- `Metadata`
|
|
- `CurrentConditions`
|
|
- `HourlyForecast`
|
|
- `DerivedDailySummary`
|
|
- `DerivedDaypartSummaries`
|
|
- ordered daypart rows
|
|
- `PrecipTiming`
|
|
- `AlertDigest`
|
|
- `SPCConvectiveOutlooks`
|
|
- `AreaForecastDiscussion`
|
|
- `SPCConvectiveDiscussion`
|
|
- `WeatherStory`
|
|
|
|
Add `TodayPlanning` only if deterministic today-specific planning facts are
|
|
introduced. Do not reuse `TomorrowPlanning` for Today.
|
|
|
|
## Module Composition
|
|
|
|
The default module composition should mirror Tomorrow where the same facts are
|
|
useful for the current-day report:
|
|
|
|
- `metadata`
|
|
- `current_conditions`
|
|
- `derived_daily_summary`
|
|
- `derived_daypart_summaries`
|
|
- `precip_timing`
|
|
- `alert_digest`
|
|
- `spc_convective_outlooks`
|
|
- `area_forecast_discussion`
|
|
- `spc_convective_discussion`
|
|
- `weather_story`
|
|
- `hourly_forecast`
|
|
|
|
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.
|
|
|
|
## Implementation Plan
|
|
|
|
1. Add Today report identity.
|
|
- Add `report.Today`.
|
|
- Add command-name and config-key support for `today`.
|
|
- Add a report definition with generated-text-template identity fields.
|
|
- Add current-local-day valid-period resolution.
|
|
- Add report tests for ID, prompt ID, artifact group, command mapping,
|
|
config key mapping, and valid period.
|
|
|
|
2. 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.
|
|
|
|
3. Add Today template and render context.
|
|
- Add `today.md.tmpl`.
|
|
- Add `TodayRenderContext`, `TodayReportContext`, and
|
|
`TodayTemplateModules`.
|
|
- Add `BuildTodayRenderContext`.
|
|
- Reuse the internal snapshot lookup helper for module extraction.
|
|
- Add render-context and template tests for populated and omitted optional
|
|
modules.
|
|
|
|
4. Register Today in the generated-text catalog and embedded asset lookups.
|
|
- Add a generated-text catalog entry.
|
|
- Add reporttemplate template/schema map entries.
|
|
- Extend catalog completeness tests.
|
|
- Add unsupported schema/template combination coverage if needed.
|
|
|
|
5. Integrate app and CLI workflows.
|
|
- Ensure `weatherreporter generate today` resolves and runs through the
|
|
generated-text-template workflow.
|
|
- 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.
|
|
|
|
6. Update current-behavior docs after implementation.
|
|
- 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/app-orchestration.md`, and maintained examples as needed.
|
|
- Keep any unresolved Daily Today replacement decision only in roadmap docs.
|
|
|
|
## Test Plan
|
|
|
|
Add or update tests for:
|
|
|
|
- report registry membership and command/config-key resolution
|
|
- 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, and daypart
|
|
ordering
|
|
- app workflow artifacts for `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:
|
|
|
|
```sh
|
|
go test ./internal/report ./internal/generatedtext ./internal/reporttemplate
|
|
go test ./internal/app ./internal/cli ./internal/config
|
|
go test ./...
|
|
go run ./cmd/weatherreporter --help
|
|
git diff --check
|
|
```
|
|
|
|
## Open Decisions
|
|
|
|
- Whether Today should eventually replace the existing Daily Today report.
|
|
- Whether morning batch should include Today, Daily Today, or both.
|
|
- Whether Today needs a dedicated deterministic planning module.
|
|
- Whether the public `daily` command should remain direct Markdown after Today
|
|
exists.
|
|
|
|
Do not resolve these decisions implicitly while adding the initial `today`
|
|
report. Keep the first implementation narrowly focused on a separate
|
|
current-day generated-text-template report.
|