Add today report roadmap

This commit is contained in:
2026-06-15 13:07:40 +00:00
parent 7cbc59d8a7
commit 7efd8b5855

261
docs/roadmap/today.md Normal file
View 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.