Update the today report template

This commit is contained in:
2026-06-15 11:01:03 -05:00
parent 63dfc0b55a
commit 58fe794227
4 changed files with 41 additions and 451 deletions

View File

@@ -1,424 +0,0 @@
# 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:
```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.
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:
```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
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:
```go
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:
```sh
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.