diff --git a/docs/config.md b/docs/config.md index c7e263c..01b3666 100644 --- a/docs/config.md +++ b/docs/config.md @@ -81,7 +81,7 @@ missing directories, and unreadable files fail config loading. `notify.distributor` controls distributor notification after successful report generation. It is disabled by default and does not add CLI flags. When enabled, weatherreporter uploads one distributor bundle per generated report after -`scriptorium run` succeeds and final metadata is saved. +report rendering succeeds and final metadata is saved. - `enabled`: whether distributor notification config is active. Default: `false`. @@ -207,6 +207,21 @@ reports: - short_term - spc_convective_discussion - hourly_forecast + hourly: + deterministic_modules: + - metadata + - current_conditions + - hourly_forecast + - precip_timing + - alert_digest + - spc_convective_outlooks + - id: area_forecast_discussion + options: + sections: + - key_messages + - short_term + - spc_convective_discussion + - weather_story ``` Unknown reports, unknown modules, duplicate modules, incompatible report/module diff --git a/docs/internal/app-orchestration.md b/docs/internal/app-orchestration.md index bd15877..abc695a 100644 --- a/docs/internal/app-orchestration.md +++ b/docs/internal/app-orchestration.md @@ -50,6 +50,19 @@ subprocess behavior stays in `internal/adapters/scriptorium`. Distributor upload behavior stays in `internal/adapters/distributor`. Filesystem layout and persisted metadata stay in `internal/state`. +## Data Flow Terms + +- `CollectedFacts` are normalized source facts fetched once from Weather API + and made available to derivation and module builders. +- `DerivedFacts` are deterministic calculations over collected facts, the + resolved valid period, daypart configuration, and report-specific windows. +- `module.Output` values are ordered deterministic stanzas built from collected + and derived facts for prompt input and inspection. +- `GeneratedText` is structured prose returned by Scriptorium for + generated-text-template reports and validated by `internal/generatedtext`. +- `RenderContext` is the typed template input built from report metadata, + module outputs, and validated generated text before Markdown rendering. + ## Config Fields Used - `weather_api.*` for Weather API client construction and module metadata diff --git a/docs/internal/prompt-input.md b/docs/internal/prompt-input.md index 95f939a..eec4562 100644 --- a/docs/internal/prompt-input.md +++ b/docs/internal/prompt-input.md @@ -73,7 +73,9 @@ converted into prompt input. The default hourly module list places `precip_timing` under `derived_summaries`, alert and SPC outlooks under `applicable_risk_products`, AFD/SPC discussion/weather story under `narrative_products`, and current/hourly data under `raw_data`. It does not -include daily or daypart summary stanzas. +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 +package. Current categories are: diff --git a/docs/internal/reporttemplate.md b/docs/internal/reporttemplate.md new file mode 100644 index 0000000..96b0073 --- /dev/null +++ b/docs/internal/reporttemplate.md @@ -0,0 +1,94 @@ +# Report Template Internals + +This document describes embedded Markdown templates and GeneratedText schemas +in `internal/reporttemplate`. + +## Purpose + +`internal/reporttemplate` owns repository-native report templates and companion +GeneratedText JSON schemas. The first implemented template contract is the +Hourly Report. + +The package embeds assets from: + +- `internal/reporttemplate/templates/*.md.tmpl` +- `internal/reporttemplate/schemas/*.schema.json` + +## Inputs And Outputs + +Inputs: + +- template ID from a report definition +- typed render context built by `internal/generatedtext` + +Outputs: + +- template source for inspection and tests +- GeneratedText schema bytes for prompt/schema configuration +- rendered Markdown bytes for app orchestration to persist + +The implemented template ID is `hourly`. The implemented schema ID is also +`hourly`, backed by `hourly.generated_text.schema.json`. + +## Boundaries + +This package owns embedded asset lookup, Go template parsing, and Markdown +template execution. It does not fetch weather data, build module outputs, +validate GeneratedText, construct render contexts, choose report definitions, +write artifacts, invoke Scriptorium, or notify distributor. + +GeneratedText validation is owned by `internal/generatedtext`. App +orchestration decides which template and schema IDs apply to a report through +`internal/report` definitions. + +## Template Contract + +Hourly rendering uses a typed render context with: + +- report metadata labels such as title, location, valid period, and generation + time +- validated hourly GeneratedText prose slots +- deterministic labels derived from module outputs, including current + conditions, hourly forecast rows, precipitation timing, alerts, SPC outlooks, + forecast discussion, SPC discussion, and weather story + +Templates use `text/template` with `missingkey=error`, so missing context fields +fail rendering instead of producing incomplete Markdown. + +## Schema Contract + +The hourly GeneratedText schema describes the structured prose Scriptorium is +expected to write for the prompt. It requires: + +- `summary` +- `timing` +- `impacts` + +It allows optional `confidence` and rejects additional properties. Weather truth +remains in module outputs; GeneratedText is limited to prose slots consumed by +the template. + +## Failure Behavior + +- Unknown template IDs return actionable lookup errors. +- Unknown schema IDs return actionable lookup errors. +- Template parse errors include the template ID. +- Template execution errors include the template ID and usually identify the + missing context field. + +## Tests + +Inspect: + +- `internal/reporttemplate/reporttemplate_test.go` +- `internal/generatedtext/render_context_test.go` +- `internal/app/app_test.go` +- `internal/cli/root_test.go` + +## Invariants + +- Embedded templates and schemas live as separate files, not inline Go strings. +- Report definitions select templates by ID. +- Templates render from curated render contexts, not raw data packages. +- GeneratedText schemas describe LLM prose slots, not deterministic weather + facts. diff --git a/docs/internal/state.md b/docs/internal/state.md index 6cf51a8..9626d5f 100644 --- a/docs/internal/state.md +++ b/docs/internal/state.md @@ -97,6 +97,8 @@ current report definition. date. - Weekend Outlook compares with prior Weekend snapshots for the same weekend window. +- Hourly Report uses the rolling-window comparison strategy and currently + returns no prior snapshot from filesystem lookup. - Storm Report has no prior lookup because explicit event-window comparison is not searched by the filesystem store. diff --git a/docs/operations.md b/docs/operations.md index 83334cd..559e8ea 100644 --- a/docs/operations.md +++ b/docs/operations.md @@ -21,10 +21,9 @@ Markdown-path generation commands resolve a report period, fetch a Weather API bundle, build a JSON module snapshot, build a YAML prompt input data package, run `scriptorium render`, run `scriptorium run`, and write managed artifacts under the configured workspace. When distributor notification is enabled, -weatherreporter uploads the managed Markdown report after `scriptorium run` +weatherreporter uploads the managed Markdown report after report rendering succeeds and final metadata is saved. `--out PATH` writes an extra Markdown -copy for Markdown-path generated reports; it is not used as the distributor -upload source. +copy for generated reports; it is not used as the distributor upload source. `generate hourly` covers the six-hour rolling period from generation time in the effective report timezone and is not part of scheduled morning or evening diff --git a/docs/roadmap/future.md b/docs/roadmap/future.md index 0a78527..ad3fd1c 100644 --- a/docs/roadmap/future.md +++ b/docs/roadmap/future.md @@ -41,7 +41,8 @@ add only modules backed by implemented upstream facts and clear report needs. Possible future report types: -- `next_6_hours` or another short-fuse planning report; +- another short-fuse planning report distinct from the implemented Hourly + Report, if a separate product is needed; - event-specific reports with stable event IDs; - storm review or yesterday-style reports using historical observations; - archive-focused report variants if generated report history becomes a @@ -84,7 +85,6 @@ These enhancements are not current behavior: - `failure_policy: warn`; - uploading metadata, module snapshots, data packages, or preflight artifacts; -- polling distributor status after upload acceptance; - durable upload retry queues; - distributor-specific CLI flags; - making distributor scan the weatherreporter workspace; diff --git a/docs/roadmap/near-term.md b/docs/roadmap/near-term.md deleted file mode 100644 index 671ea5b..0000000 --- a/docs/roadmap/near-term.md +++ /dev/null @@ -1,6 +0,0 @@ -# Superseded Roadmap - -This roadmap has been superseded by `docs/roadmap/generated-text.md`. - -The rolling next-hours report is named `hourly`. Use the GeneratedText roadmap -for current future-work guidance.