Add today report roadmap
This commit is contained in:
261
docs/roadmap/today.md
Normal file
261
docs/roadmap/today.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user