Document Today report workflow

This commit is contained in:
2026-06-15 15:04:14 +00:00
parent 4a0238909b
commit 1ddc33eb17
13 changed files with 181 additions and 49 deletions

View File

@@ -9,7 +9,7 @@ Markdown reports to a configured `distributor` HTTP upload endpoint.
## Quickstart ## Quickstart
```sh ```sh
weatherreporter generate daily --date 2026-05-29 --out ./daily.md weatherreporter generate today --out ./today.md
``` ```
## Documentation ## Documentation

View File

@@ -6,14 +6,15 @@ batches, and inspects stored artifacts.
## Shortest Useful Command ## Shortest Useful Command
```sh ```sh
weatherreporter generate daily --date 2026-05-29 --out ./daily.md weatherreporter generate today --out ./today.md
``` ```
This loads configuration, fetches weather data, writes managed workspace This loads configuration, fetches weather data, writes managed workspace
artifacts, runs `scriptorium render` as a preflight check, runs artifacts, runs `scriptorium render` as a preflight check, runs structured
`scriptorium run`, and writes an extra Markdown copy to `./daily.md`. If `scriptorium run`, validates generated text, renders the embedded Today
distributor notification is enabled in configuration, the command also uploads template, and writes an extra Markdown copy to `./today.md`. If distributor
the managed Markdown report after final metadata is saved. notification is enabled in configuration, the command also uploads the managed
Markdown report after final metadata is saved.
## Commands ## Commands
@@ -47,6 +48,10 @@ the effective report timezone and does not accept date or event window flags.
`generate storm` requires explicit event-window bounds with `--start` and `generate storm` requires explicit event-window bounds with `--start` and
`--end`. `--end`.
`generate daily` remains the existing Daily Today report. It is separate from
`generate today`; the commands use different report IDs, artifact groups,
prompts, and config override keys.
`run morning` generates Today Report and the 3-Day Outlook, plus Weekend Outlook `run morning` generates Today Report and the 3-Day Outlook, plus Weekend Outlook
except on Sunday. `run evening` generates the Tomorrow Report. Batch except on Sunday. `run evening` generates the Tomorrow Report. Batch
runs continue independent reports after a failure, print a JSON summary to runs continue independent reports after a failure, print a JSON summary to
@@ -85,8 +90,9 @@ are no distributor-specific CLI flags.
## Common Workflows ## Common Workflows
```sh ```sh
weatherreporter generate tomorrow --out ./tomorrow.md
weatherreporter generate today --out ./today.md weatherreporter generate today --out ./today.md
weatherreporter generate daily --date 2026-05-29 --out ./daily.md
weatherreporter generate tomorrow --out ./tomorrow.md
weatherreporter generate hourly weatherreporter generate hourly
weatherreporter generate three-day --out ./three-day.md weatherreporter generate three-day --out ./three-day.md
weatherreporter generate weekend --out ./weekend.md weatherreporter generate weekend --out ./weekend.md
@@ -99,11 +105,12 @@ weatherreporter run evening --out-dir ./reports
```sh ```sh
weatherreporter inspect reports --limit 10 weatherreporter inspect reports --limit 10
weatherreporter inspect metadata 20260529T100000.000000000Z_today
weatherreporter inspect modules 20260529T100000.000000000Z_today
weatherreporter inspect data-package 20260529T100000.000000000Z_today
weatherreporter inspect prior 20260529T100000.000000000Z_today
weatherreporter inspect sources 20260529T100000.000000000Z_today
weatherreporter inspect metadata 20260529T100000.000000000Z_daily_today weatherreporter inspect metadata 20260529T100000.000000000Z_daily_today
weatherreporter inspect modules 20260529T100000.000000000Z_daily_today
weatherreporter inspect data-package 20260529T100000.000000000Z_daily_today
weatherreporter inspect prior 20260529T100000.000000000Z_daily_today
weatherreporter inspect sources 20260529T100000.000000000Z_daily_today
``` ```
`inspect reports` lists recent generated runs with artifact paths and source `inspect reports` lists recent generated runs with artifact paths and source

View File

@@ -181,11 +181,14 @@ snapshot exists and a threshold is crossed.
`reports` optionally overrides the ordered deterministic modules declared by `reports` optionally overrides the ordered deterministic modules declared by
report definitions. Omit a report entry to use its default module order. report definitions. Omit a report entry to use its default module order.
Supported report keys are `daily`, `tomorrow`, `hourly`, `three_day`, Supported report keys are `daily`, `today`, `tomorrow`, `hourly`,
`weekend`, and `storm`. Canonical report IDs and accepted aliases are also `three_day`, `weekend`, and `storm`. Canonical report IDs and accepted aliases
valid, including `daily_today`, `three_day_outlook`, `weekend_outlook`, and are also valid, including `daily_today`, `three_day_outlook`,
`storm_report`. Hyphens and underscores are treated equivalently in report `weekend_outlook`, and `storm_report`. Hyphens and underscores are treated
keys. equivalently in report keys.
`reports.today` applies only to the Today Report. `reports.daily` and
`reports.daily_today` apply only to the existing Daily Today report.
Each report entry supports: Each report entry supports:
@@ -209,6 +212,22 @@ reports:
- short_term - short_term
- spc_convective_discussion - spc_convective_discussion
- hourly_forecast - hourly_forecast
today:
deterministic_modules:
- 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
hourly: hourly:
deterministic_modules: deterministic_modules:
- metadata - metadata

View File

@@ -42,6 +42,10 @@ Tomorrow Report supports the Daily-style civil-day modules plus
`tomorrow_planning` and `hourly_forecast`; those outputs feed the Tomorrow `tomorrow_planning` and `hourly_forecast`; those outputs feed the Tomorrow
GeneratedText prompt package and embedded Markdown template. GeneratedText prompt package and embedded Markdown template.
Today Report supports the Daily-style civil-day modules plus `today_planning`
and `hourly_forecast`; those outputs feed the Today GeneratedText prompt
package and embedded Markdown template.
`today_planning` is a Today-specific deterministic planning stanza with `today_planning` is a Today-specific deterministic planning stanza with
morning readiness, commute/school/workday concerns, outdoor planning, and morning readiness, commute/school/workday concerns, outdoor planning, and
late-day change-watch fields. It is compatible with `report.Today` only. late-day change-watch fields. It is compatible with `report.Today` only.

View File

@@ -9,9 +9,8 @@ This document describes structured generated-text handling in
generated-text-template reports and builds curated render contexts for generated-text-template reports and builds curated render contexts for
templates. It also owns the generated-text catalog that connects report templates. It also owns the generated-text catalog that connects report
definitions to validators, render-context builders, schema assets, and template definitions to validators, render-context builders, schema assets, and template
assets. The implemented contracts are Today, Tomorrow Report, and Hourly assets. The implemented contracts are Today Report, Tomorrow Report, and Hourly
Report. Today support is internal until a report definition references the Report.
`today` schema and template IDs.
## Inputs And Outputs ## Inputs And Outputs
@@ -50,7 +49,9 @@ The hourly generated text JSON accepts:
JSON when blank. JSON when blank.
The Today generated text JSON accepts the same public fields and validation The Today generated text JSON accepts the same public fields and validation
rules as Tomorrow: rules as Tomorrow. It is selected by the active Today report definition through
schema ID `today`, template ID `today`, and prompt ID
`weather.today_generated_text`:
```json ```json
{ {

View File

@@ -48,6 +48,28 @@ The registry recognizes these IDs:
Every registered module has a builder. Report composition entries that refer to Every registered module has a builder. Report composition entries that refer to
unknown or unimplemented module IDs fail validation instead of being skipped. unknown or unimplemented module IDs fail validation instead of being skipped.
## Today Composition
The default Today Report module order is:
1. `metadata`
2. `current_conditions`
3. `narrative_forecast`
4. `derived_daily_summary`
5. `derived_daypart_summaries`
6. `precip_timing`
7. `alert_digest`
8. `spc_convective_outlooks`
9. `area_forecast_discussion`
10. `spc_convective_discussion`
11. `weather_story`
12. `outdoor_windows`
13. `hourly_forecast`
14. `today_planning`
The embedded Today template uses selected deterministic fields from these
module outputs after GeneratedText validation.
## Tomorrow Composition ## Tomorrow Composition
The default Tomorrow Report module order is: The default Tomorrow Report module order is:
@@ -70,6 +92,24 @@ The default Tomorrow Report module order is:
The embedded Tomorrow template uses selected deterministic fields from these The embedded Tomorrow template uses selected deterministic fields from these
module outputs after GeneratedText validation. module outputs after GeneratedText validation.
## Today Planning
`today_planning` emits current-day planning facts for Today Report. Its output
stanza is also named `today_planning`. The module is supported only by Today
Report and depends on daily and daypart summaries for the current local civil
day.
The output uses the same shape as Tomorrow planning:
- `morning_readiness`
- `commute`
- `outdoor_planning`
- `things_to_watch`
- `confidence`
The type is `briefing.TodayPlanningModule`; it is independent from
`briefing.TomorrowPlanningModule`.
## Hourly Composition ## Hourly Composition
The default Hourly Report module order is: The default Hourly Report module order is:

View File

@@ -68,9 +68,9 @@ Prompt-facing module intervals use local `period_begins` and `period_ends`
labels; canonical report metadata and source timestamps remain structured labels; canonical report metadata and source timestamps remain structured
timestamps where applicable. timestamps where applicable.
Tomorrow Report and Hourly Report module snapshots use the same package schema Today Report, Tomorrow Report, and Hourly Report module snapshots use the same
and categories when converted into prompt input. The default hourly module list package schema and categories when converted into prompt input. The default
places hourly module list places
`precip_timing` under `derived_summaries`, alert and SPC outlooks under `precip_timing` under `derived_summaries`, alert and SPC outlooks under
`applicable_risk_products`, AFD/SPC discussion/weather story under `applicable_risk_products`, AFD/SPC discussion/weather story under
`narrative_products`, and current/hourly data under `raw_data`. It does not `narrative_products`, and current/hourly data under `raw_data`. It does not
@@ -78,9 +78,10 @@ include civil-day summary stanzas. Generated-text and render context artifacts
are produced later in app orchestration and are not part of the YAML data are produced later in app orchestration and are not part of the YAML data
package. package.
The default Tomorrow module list includes civil-day summary stanzas, The default Today and Tomorrow module lists include civil-day summary stanzas,
`tomorrow_planning`, and `hourly_forecast` in the data package before planning stanzas, and `hourly_forecast` in the data package before structured
structured GeneratedText is requested from Scriptorium. GeneratedText is requested from Scriptorium. Today uses `today_planning`;
Tomorrow uses `tomorrow_planning`.
Current categories are: Current categories are:

View File

@@ -33,6 +33,10 @@ The generate command names are `daily`, `today`, `tomorrow`, `hourly`,
legacy descriptive aliases such as `daily_today`, `three_day_outlook`, legacy descriptive aliases such as `daily_today`, `three_day_outlook`,
`weekend_outlook`, and `storm_report`. `weekend_outlook`, and `storm_report`.
`daily` resolves to the existing Daily Today report ID `daily_today`.
`today` resolves to the independent Today report ID `today`. `reports.today`
is not an alias for `reports.daily` or `reports.daily_today`.
Markdown report definitions use the `scriptorium_markdown` generation mode. Markdown report definitions use the `scriptorium_markdown` generation mode.
Their template and structured-text schema identifiers are empty. Today Report, Their template and structured-text schema identifiers are empty. Today Report,
Tomorrow Report, and Hourly Report declare `generated_text_template`; the app Tomorrow Report, and Hourly Report declare `generated_text_template`; the app
@@ -88,7 +92,7 @@ report override keys.
The app supplies `weather_api.timezone` as a loaded `time.Location`. Batch The app supplies `weather_api.timezone` as a loaded `time.Location`. Batch
output path copying uses batch output names from report definitions. Report output path copying uses batch output names from report definitions. Report
module overrides can use short keys such as `today`, `tomorrow`, and `hourly`, module overrides can use short keys such as `today`, `tomorrow`, and `hourly`,
canonical report IDs such as `daily_today`, or accepted aliases such as canonical report IDs such as `daily_today`, or descriptive names such as
`three_day_outlook`. `three_day_outlook`.
## Batch Membership ## Batch Membership

View File

@@ -6,9 +6,8 @@ in `internal/reporttemplate`.
## Purpose ## Purpose
`internal/reporttemplate` owns repository-native report templates and companion `internal/reporttemplate` owns repository-native report templates and companion
GeneratedText JSON schemas. The implemented template contracts are Today, GeneratedText JSON schemas. The implemented template contracts are Today
Tomorrow Report, and Hourly Report. Today assets are available internally until Report, Tomorrow Report, and Hourly Report.
a report definition selects them.
The package embeds assets from: The package embeds assets from:
@@ -36,6 +35,10 @@ The implemented template IDs are `today`, `tomorrow`, and `hourly`. The
implemented schema IDs are also `today`, `tomorrow`, and `hourly`, backed by implemented schema IDs are also `today`, `tomorrow`, and `hourly`, backed by
matching `*.generated_text.schema.json` files. matching `*.generated_text.schema.json` files.
The Today generated-text prompt source is
`internal/reporttemplate/prompts/today.generated_text.md`, selected by prompt
ID `weather.today_generated_text`.
## Boundaries ## Boundaries
This package owns embedded asset lookup, Go template parsing, and Markdown This package owns embedded asset lookup, Go template parsing, and Markdown

View File

@@ -10,6 +10,7 @@ Generation commands:
```text ```text
weatherreporter generate daily --date 2026-05-29 weatherreporter generate daily --date 2026-05-29
weatherreporter generate today
weatherreporter generate tomorrow weatherreporter generate tomorrow
weatherreporter generate hourly weatherreporter generate hourly
weatherreporter generate three-day weatherreporter generate three-day
@@ -23,12 +24,16 @@ a JSON module snapshot, build a YAML prompt input data package, run
workspace. Markdown-path reports then run `scriptorium run` directly to the workspace. Markdown-path reports then run `scriptorium run` directly to the
managed Markdown report path. managed Markdown report path.
`generate tomorrow` and `generate hourly` use the generated-text-template `generate today`, `generate tomorrow`, and `generate hourly` use the
workflow. They run structured `scriptorium run` to raw GeneratedText JSON, generated-text-template workflow. They run structured `scriptorium run` to raw
validate the structured text, save a render context, and render the managed GeneratedText JSON, validate the structured text, save a render context, and
Markdown report from embedded templates. `generate hourly` covers the six-hour render the managed Markdown report from embedded templates. `generate today`
rolling period from generation time in the effective report timezone and is not covers the selected or current local civil day. `generate hourly` covers the
part of scheduled morning or evening batches. six-hour rolling period from generation time in the effective report timezone
and is not part of scheduled morning or evening batches.
`generate daily` remains the existing Daily Today report and is independent of
`generate today`.
When distributor notification is enabled, weatherreporter uploads the managed When distributor notification is enabled, weatherreporter uploads the managed
Markdown report after report rendering succeeds and final metadata is saved. Markdown report after report rendering succeeds and final metadata is saved.
@@ -42,14 +47,14 @@ weatherreporter run morning
weatherreporter run evening weatherreporter run evening
``` ```
`run morning` generates Daily Today and the 3-Day Outlook, plus Weekend Outlook `run morning` generates Today Report and the 3-Day Outlook, plus Weekend Outlook
except on Sunday. `run evening` generates the Tomorrow Report. Batch except on Sunday. `run evening` generates the Tomorrow Report. Batch
commands print a JSON summary to stdout, write compact per-report status lines commands print a JSON summary to stdout, write compact per-report status lines
to stderr, continue independent reports after one report fails, and return to stderr, continue independent reports after one report fails, and return
nonzero when any report failed. When notification is configured, the summary and nonzero when any report failed. When notification is configured, the summary and
status lines include notification status, accepted distributor run ID, or status lines include notification status, accepted distributor run ID, or
notification error fields for each attempted report. `--out-dir PATH` writes notification error fields for each attempted report. `--out-dir PATH` writes
extra Markdown copies using report default filenames such as `daily.md`, extra Markdown copies using report default filenames such as `today.md`,
`three-day.md`, `weekend.md`, and `tomorrow.md`; these copies are not used as `three-day.md`, `weekend.md`, and `tomorrow.md`; these copies are not used as
distributor upload sources. distributor upload sources.
@@ -64,6 +69,14 @@ workspace/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.modules.json <run_id>.modules.json
<run_id>.metadata.json <run_id>.metadata.json
today/
YYYY-MM-DD/
<run_id>.modules.json
<run_id>.metadata.json
<run_id>.generated_text.raw.json
<run_id>.generated_text.run.json
<run_id>.generated_text.json
<run_id>.render_context.json
three-day/ three-day/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.modules.json <run_id>.modules.json
@@ -96,6 +109,9 @@ workspace/
daily/ daily/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.data_package.yaml <run_id>.data_package.yaml
today/
YYYY-MM-DD/
<run_id>.data_package.yaml
three-day/ three-day/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.data_package.yaml <run_id>.data_package.yaml
@@ -115,6 +131,9 @@ workspace/
daily/ daily/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.render.json <run_id>.render.json
today/
YYYY-MM-DD/
<run_id>.render.json
three-day/ three-day/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.render.json <run_id>.render.json
@@ -134,6 +153,9 @@ workspace/
daily/ daily/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.distributor.json <run_id>.distributor.json
today/
YYYY-MM-DD/
<run_id>.distributor.json
three-day/ three-day/
YYYY-MM-DD/ YYYY-MM-DD/
<run_id>.distributor.json <run_id>.distributor.json
@@ -152,6 +174,8 @@ workspace/
reports/ reports/
daily/ daily/
<run_id>.md <run_id>.md
today/
<run_id>.md
three-day/ three-day/
<run_id>.md <run_id>.md
weekend/ weekend/
@@ -173,6 +197,7 @@ RunIDs are based on generation time plus report ID:
```text ```text
20260529T100000.123456789Z_daily_today 20260529T100000.123456789Z_daily_today
20260529T100000.123456789Z_today
``` ```
Each generated report writes metadata that links: Each generated report writes metadata that links:
@@ -214,6 +239,8 @@ The default idempotency key appends RunID to the rendered bundle ID so each
report generation has a distinct retry identity. The default bundle path uses report generation has a distinct retry identity. The default bundle path uses
the valid-period start date, artifact group, and RunID. Distributor owns the valid-period start date, artifact group, and RunID. Distributor owns
destination merge, retention, and derived snapshot behavior such as `latest`. destination merge, retention, and derived snapshot behavior such as `latest`.
For Today, the default report ID and artifact group values are both `today`,
and the batch output filename value is `today.md`.
Notification happens after final metadata save for generated reports. Weather Notification happens after final metadata save for generated reports. Weather
API, module snapshot, data-package, render preflight, Scriptorium run, API, module snapshot, data-package, render preflight, Scriptorium run,
@@ -267,11 +294,12 @@ Recent Changes are computed from structured module snapshots, not rendered
Markdown or YAML text. Markdown or YAML text.
Daily Today compares with prior Daily Today snapshots for the same valid local Daily Today compares with prior Daily Today snapshots for the same valid local
date. Tomorrow Report compares with prior Tomorrow Report snapshots for the date. Today Report compares with prior Today Report snapshots for the same
same valid local date. 3-Day Outlook compares with prior compatible 3-Day valid local date. Tomorrow Report compares with prior Tomorrow Report snapshots
snapshots for the same valid local date. Weekend Outlook compares with prior for the same valid local date. 3-Day Outlook compares with prior compatible
compatible Weekend snapshots for the same weekend window. Hourly Report and 3-Day snapshots for the same valid local date. Weekend Outlook compares with
Storm Report leave Recent Changes empty. prior compatible Weekend snapshots for the same weekend window. Hourly Report
and Storm Report leave Recent Changes empty.
When no prior comparable snapshot exists, or no configured threshold is crossed, When no prior comparable snapshot exists, or no configured threshold is crossed,
`recentChanges.items` is empty. `recentChanges.items` is empty.
@@ -284,10 +312,10 @@ A failed generation run may still leave useful artifacts:
preflight JSON and metadata are written for inspection. preflight JSON and metadata are written for inspection.
- If `scriptorium run` exits nonzero after writing a report, the managed report - If `scriptorium run` exits nonzero after writing a report, the managed report
and metadata remain available. and metadata remain available.
- Hourly generated-text failures preserve available intermediate artifacts, - Generated-text failures for Today, Tomorrow, and Hourly reports preserve
such as the structured run result, raw generated-text JSON, validated available intermediate artifacts, such as the structured run result, raw
generated text, and render context. Metadata links those paths when it can be generated-text JSON, validated generated text, and render context. Metadata
safely written. links those paths when it can be safely written.
- If distributor notification fails, report artifacts and final metadata remain - If distributor notification fails, report artifacts and final metadata remain
available, but the report or batch command returns nonzero. available, but the report or batch command returns nonzero.
- For batch commands, inspect the stdout JSON summary first, then inspect the - For batch commands, inspect the stdout JSON summary first, then inspect the

View File

@@ -130,6 +130,9 @@ Today generated text uses `.GeneratedText.Summary`,
`.GeneratedText.Confidence`. Forecast discussion is a slice of paragraphs and `.GeneratedText.Confidence`. Forecast discussion is a slice of paragraphs and
should be rendered with `range`. should be rendered with `range`.
Today uses template ID `today`, generated-text schema ID `today`, and prompt
source `internal/reporttemplate/prompts/today.generated_text.md`.
Today modules include the Hourly module fields plus: Today modules include the Hourly module fields plus:
| Variable | Type | Description | | Variable | Type | Description |

View File

@@ -187,7 +187,7 @@ Relevant docs: [Operations guide](operations.md),
## Generated Text Validation Fails ## Generated Text Validation Fails
Symptom: Tomorrow or Hourly generation fails with generated-text decode, Symptom: Today, Tomorrow, or Hourly generation fails with generated-text decode,
unknown-field, required-field, or multiple-JSON-values context. unknown-field, required-field, or multiple-JSON-values context.
Likely cause: Scriptorium wrote structured JSON that does not match the Likely cause: Scriptorium wrote structured JSON that does not match the
@@ -210,7 +210,7 @@ Relevant docs: [Operations guide](operations.md),
## Template Rendering Fails ## Template Rendering Fails
Symptom: Tomorrow or Hourly generation fails with report template parsing or Symptom: Today, Tomorrow, or Hourly generation fails with report template parsing or
execution context after generated text validation succeeds. execution context after generated text validation succeeds.
Likely cause: an embedded template references a missing context field or Likely cause: an embedded template references a missing context field or

View File

@@ -89,6 +89,28 @@ reports:
- weather_story - weather_story
- outdoor_windows - outdoor_windows
- hourly_forecast - hourly_forecast
today:
deterministic_modules:
- metadata
- current_conditions
- narrative_forecast
- derived_daily_summary
- derived_daypart_summaries
- precip_timing
- alert_digest
- spc_convective_outlooks
- id: area_forecast_discussion
options:
sections:
- product
- key_messages
- short_term
- long_term
- spc_convective_discussion
- weather_story
- outdoor_windows
- hourly_forecast
- today_planning
hourly: hourly:
deterministic_modules: deterministic_modules:
- metadata - metadata