277 lines
9.7 KiB
Markdown
277 lines
9.7 KiB
Markdown
# Tomorrow Report Roadmap
|
|
|
|
## Purpose
|
|
|
|
This roadmap defines the target state for making Tomorrow an independent
|
|
generated-text-template report. The feature is not implemented yet, so this
|
|
document lives under `docs/roadmap/`.
|
|
|
|
## Intent
|
|
|
|
Tomorrow should become its own report product, not a variant of the Daily
|
|
Report. The current CLI command `weatherreporter generate tomorrow` should
|
|
remain, but the internal report ID, prompt ID, template, schema, workspace
|
|
paths, and distributor identity should use `tomorrow`.
|
|
|
|
The report should combine deterministic daypart and precipitation facts with
|
|
LLM prose for the high-level summary, optional precipitation context, and
|
|
forecast discussion. The resulting Markdown should be predictable and
|
|
template-driven, similar to the implemented Hourly Report.
|
|
|
|
Longer term, Today, Tomorrow, and Daily may all become separate report products
|
|
with different prompts, templates, and deterministic sections. This roadmap
|
|
starts that split with Tomorrow.
|
|
|
|
## Target Report Shape
|
|
|
|
Example structure:
|
|
|
|
```markdown
|
|
# Sunday's Weather
|
|
|
|
**Forecast Date:** Sunday, June 15, 2026
|
|
**Generated:** Saturday, June 14, 2026 at 9:14 AM
|
|
|
|
<GeneratedText summary>
|
|
|
|
## Daypart Forecast
|
|
|
|
- **Overnight:** <deterministic daypart line>
|
|
- **Morning:** <deterministic daypart line>
|
|
- **Midday:** <deterministic daypart line>
|
|
- **Afternoon:** <deterministic daypart line>
|
|
- **Evening:** <deterministic daypart line>
|
|
|
|
## Precipitation Timing
|
|
|
|
- **1:00 AM** to **5:00 AM**: Precipitation is expected during this period. The peak precipitation chance is 59% at 2:00 AM.
|
|
- <optional GeneratedText precipitation_timing>
|
|
|
|
## Forecast Discussion
|
|
|
|
<GeneratedText forecast_discussion paragraphs>
|
|
```
|
|
|
|
`Precipitation Timing` should render only when at least one precipitation
|
|
window exists for the valid period. The threshold for precipitation windows
|
|
remains the existing precipitation-window threshold, currently 40%.
|
|
|
|
## Locked Decisions
|
|
|
|
- Replace report ID `daily_tomorrow` with `tomorrow`.
|
|
- Do not preserve compatibility aliases for `daily_tomorrow`; this is a
|
|
pre-release clean break.
|
|
- Keep public CLI syntax: `weatherreporter generate tomorrow`.
|
|
- Use generated-text-template generation for Tomorrow, not full Markdown
|
|
generation by Scriptorium.
|
|
- Use a dedicated Scriptorium prompt ID, template ID, and schema ID:
|
|
- prompt ID: `weather.tomorrow_generated_text`
|
|
- template ID: `tomorrow`
|
|
- generated-text schema ID: `tomorrow`
|
|
- Use `ArtifactGroup: "tomorrow"` and `BatchOutputName: "tomorrow.md"`.
|
|
- Use `CompatiblePriorIDs: []report.ID{report.Tomorrow}`.
|
|
- Keep valid-period behavior: Tomorrow covers the next local civil day.
|
|
- Keep Morning/Evening batch behavior unless explicitly changed later; evening
|
|
batch should still include Tomorrow.
|
|
- Future Today/Daily split is out of scope for this roadmap.
|
|
|
|
## GeneratedText Contract
|
|
|
|
Add a Tomorrow GeneratedText schema:
|
|
|
|
```json
|
|
{
|
|
"summary": "string",
|
|
"forecast_discussion": ["string"],
|
|
"precipitation_timing": "string",
|
|
"confidence": "string"
|
|
}
|
|
```
|
|
|
|
Required:
|
|
|
|
- `summary`
|
|
- `forecast_discussion`
|
|
|
|
Optional:
|
|
|
|
- `precipitation_timing`
|
|
- `confidence`
|
|
|
|
`forecast_discussion` should be an array of paragraph strings so Scriptorium
|
|
can return multi-paragraph discussion without embedding paragraph delimiters in
|
|
one string. Empty or whitespace-only discussion paragraphs should be rejected or
|
|
trimmed out during validation; after trimming, at least one paragraph is
|
|
required.
|
|
|
|
`confidence` may be validated and persisted but does not need to render in the
|
|
initial template.
|
|
|
|
## Template Context
|
|
|
|
Add a dedicated Tomorrow render context rather than reusing Hourly context
|
|
types.
|
|
|
|
Recommended top-level shape:
|
|
|
|
```go
|
|
type TomorrowRenderContext struct {
|
|
Report TomorrowReportContext
|
|
GeneratedText Tomorrow
|
|
Modules TomorrowTemplateModules
|
|
Collected facts.CollectedFacts
|
|
Derived facts.DerivedFacts
|
|
}
|
|
```
|
|
|
|
`TomorrowReportContext` should include:
|
|
|
|
- `Title`: for example `Sunday's Weather`
|
|
- `ForecastDate`: canonical local forecast date if useful
|
|
- `ForecastDateLabel`: for example `Sunday, June 15, 2026`
|
|
- `ForecastDayName`: for example `Sunday`
|
|
- `GeneratedAt`
|
|
- `GeneratedAtLabel`: for example `Saturday, June 14, 2026 at 9:14 AM`
|
|
- `ValidPeriod`
|
|
- `Timezone`
|
|
|
|
Do not derive the possessive title in the template. Go should provide `Title`
|
|
so wording is consistent and easy to test.
|
|
|
|
`TomorrowTemplateModules` should expose the module outputs needed by the
|
|
template:
|
|
|
|
- `Metadata`
|
|
- `DerivedDailySummary`
|
|
- `DerivedDaypartSummaries`
|
|
- `PrecipTiming`
|
|
- `AlertDigest`
|
|
- `SPCConvectiveOutlooks`
|
|
- `AreaForecastDiscussion`
|
|
- `SPCConvectiveDiscussion`
|
|
- `WeatherStory`
|
|
- `TomorrowPlanning`, if still useful
|
|
|
|
Current conditions and hourly forecast can remain in the module snapshot and
|
|
data package if useful for Scriptorium, but they do not need to render in the
|
|
initial Tomorrow template unless a later design calls for them.
|
|
|
|
## Daypart Forecast
|
|
|
|
The Daypart Forecast should be deterministic but composable. Avoid adding a
|
|
single prewritten Go `DaypartLine` string that makes template wording rigid.
|
|
|
|
Add presentation-friendly fields to `derived_daypart_summaries` only where they
|
|
avoid awkward template logic. Likely useful fields:
|
|
|
|
- display name, such as `Overnight` or `Morning`;
|
|
- lower-case dominant condition text for inline sentences;
|
|
- rounded temperature range phrase if available;
|
|
- precipitation mention flag using the existing hourly line mention threshold
|
|
concept, currently 20%;
|
|
- max precipitation probability and friendly max time;
|
|
- optional wind phrase or wind range only if deterministic wind wording is
|
|
clearly needed.
|
|
|
|
The initial implementation may keep daypart bullet wording simple. It should be
|
|
easy to revise the template text without editing Go unless new facts are
|
|
needed.
|
|
|
|
## Implementation Plan
|
|
|
|
1. Report identity split
|
|
- Rename `report.DailyTomorrow` to `report.Tomorrow` with ID `tomorrow`.
|
|
- Update registry order, resolver references, CLI mapping, batch selection,
|
|
state metadata expectations, docs, and tests.
|
|
- Preserve `weatherreporter generate tomorrow`.
|
|
- Accept that workspace paths, RunIDs, distributor bundle IDs, and report
|
|
URLs change from `daily_tomorrow` to `tomorrow`.
|
|
|
|
2. GeneratedText contract
|
|
- Add `generatedtext.Tomorrow`, validation, normalized JSON output, and
|
|
tests.
|
|
- Add `tomorrow.generated_text.schema.json`.
|
|
- Add `internal/reporttemplate/prompts/tomorrow.generated_text.md` as the
|
|
maintained prompt source asset.
|
|
- Update app validation dispatch to use the Tomorrow schema.
|
|
|
|
3. Template and render context
|
|
- Add `internal/reporttemplate/templates/tomorrow.md.tmpl`.
|
|
- Add Tomorrow template/schema lookup entries.
|
|
- Add `BuildTomorrowRenderContext`.
|
|
- Update app render-context dispatch for template ID `tomorrow`.
|
|
- Persist render context in the existing generated-text-template workflow.
|
|
|
|
4. Module presentation fields
|
|
- Add only the daypart presentation fields needed by the template.
|
|
- Reuse the existing precipitation window hour-label fields.
|
|
- Keep deterministic weather derivation in Go and wording/layout in the
|
|
template.
|
|
|
|
5. Report definition conversion
|
|
- Change Tomorrow report definition to:
|
|
- `PromptID: "weather.tomorrow_generated_text"`
|
|
- `GenerationMode: generated_text_template`
|
|
- `TemplateID: "tomorrow"`
|
|
- `GeneratedTextSchemaID: "tomorrow"`
|
|
- `ArtifactGroup: "tomorrow"`
|
|
- `BatchOutputName: "tomorrow.md"`
|
|
- compatible prior IDs containing only `tomorrow`
|
|
- Review module composition and keep only modules used by the prompt,
|
|
template, or future inspection value.
|
|
|
|
6. Documentation and examples
|
|
- After implementation, update non-roadmap docs for implemented behavior:
|
|
`docs/cli.md`, `docs/operations.md`, `docs/internal/report-registry.md`,
|
|
`docs/internal/generatedtext.md`, `docs/internal/reporttemplate.md`, and
|
|
`docs/templates.md`.
|
|
- Update examples that refer to `reports.tomorrow` or report module
|
|
overrides if the config key changes.
|
|
|
|
## Test Plan
|
|
|
|
- Report tests:
|
|
- registry contains `tomorrow`, not `daily_tomorrow`;
|
|
- `generate tomorrow` resolves report ID `tomorrow`;
|
|
- valid period remains next local civil day;
|
|
- evening batch still includes Tomorrow;
|
|
- RunID and artifact paths use `tomorrow`.
|
|
- GeneratedText tests:
|
|
- `summary` and non-empty `forecast_discussion` are required;
|
|
- `forecast_discussion` trims paragraph strings and rejects/omits blanks;
|
|
- optional `precipitation_timing` and `confidence` normalize correctly;
|
|
- unknown fields are rejected.
|
|
- Template tests:
|
|
- title renders as `<weekday>'s Weather`;
|
|
- forecast date and generated labels render;
|
|
- daypart bullets render in configured daypart order;
|
|
- precipitation section is omitted when no precipitation windows exist;
|
|
- precipitation section includes deterministic windows and optional LLM text
|
|
when windows exist;
|
|
- forecast discussion renders multiple paragraphs.
|
|
- App/CLI workflow tests:
|
|
- `weatherreporter generate tomorrow` uses structured Scriptorium output and
|
|
the template renderer;
|
|
- raw generated text, validated generated text, render context, report, and
|
|
metadata artifacts are persisted;
|
|
- optional `--out` behavior remains unchanged;
|
|
- distributor notification uses report ID/artifact group `tomorrow`.
|
|
|
|
Validation commands:
|
|
|
|
```bash
|
|
go test ./internal/report ./internal/generatedtext ./internal/reporttemplate ./internal/briefing ./internal/app ./internal/cli ./internal/state
|
|
go test ./...
|
|
go run ./cmd/weatherreporter --help
|
|
git diff --check
|
|
```
|
|
|
|
## Open Questions
|
|
|
|
None block implementation. Recommended defaults are:
|
|
|
|
- make `forecast_discussion` an array of strings for Tomorrow;
|
|
- keep Hourly GeneratedText unchanged for now;
|
|
- do not add Daily Today or generic Daily report splits in this change;
|
|
- do not preserve `daily_tomorrow` compatibility aliases.
|