Clarify module package documentation

This commit is contained in:
2026-06-09 21:42:38 +00:00
parent d665049f05
commit 1ddd88231a
12 changed files with 197 additions and 114 deletions

View File

@@ -1,7 +1,7 @@
# Weatherreporter CLI # Weatherreporter CLI
`weatherreporter` generates Markdown weather reports, runs scheduled report `weatherreporter` generates Markdown weather reports, runs scheduled report
batches, and inspects previously generated artifacts. batches, and inspects stored artifacts.
## Shortest Useful Command ## Shortest Useful Command
@@ -34,11 +34,11 @@ weatherreporter inspect prior [--config PATH] RUN_ID
weatherreporter inspect sources [--config PATH] RUN_ID weatherreporter inspect sources [--config PATH] RUN_ID
``` ```
`generate` commands write module snapshot, data package, preflight, `generate` commands write a JSON module snapshot, YAML data package, preflight
report, and metadata artifacts under the configured workspace. `--out` writes artifact, managed Markdown report, and metadata under the configured workspace.
an extra Markdown copy for the operator; distributor notification uses the `--out` writes an extra Markdown copy for the operator; distributor
managed report path, not the extra copy. `generate storm` requires explicit notification uses the managed report path, not the extra copy. `generate storm`
event-window bounds with `--start` and `--end`. requires explicit event-window bounds with `--start` and `--end`.
`run morning` generates Daily Today and the 3-Day Outlook, plus Weekend Outlook `run morning` generates Daily Today and the 3-Day Outlook, plus Weekend Outlook
except on Sunday. `run evening` generates the Tomorrow Planning Brief. Batch except on Sunday. `run evening` generates the Tomorrow Planning Brief. Batch

View File

@@ -16,9 +16,9 @@ Precedence is:
2. configuration file 2. configuration file
3. built-in defaults 3. built-in defaults
The implemented configuration overrides are `--units` and `--tz`. Output flags The CLI configuration overrides are `--units` and `--tz`. Output flags control
control report copies for the current command but do not change configuration report copies for the current command but do not change configuration files.
files. Environment variables do not override configuration fields. Environment variables do not override configuration fields.
## Minimal Config ## Minimal Config
@@ -177,8 +177,7 @@ snapshot exists and a threshold is crossed.
### `reports` ### `reports`
`reports` optionally overrides the ordered deterministic modules declared by `reports` optionally overrides the ordered deterministic modules declared by
built-in report definitions. Omit a report entry to use its built-in module report definitions. Omit a report entry to use its default module order.
order.
Supported report keys are `daily`, `tomorrow`, `three_day`, `weekend`, and Supported report keys are `daily`, `tomorrow`, `three_day`, `weekend`, and
`storm`. Canonical report IDs such as `daily_today` and `daily_tomorrow` are `storm`. Canonical report IDs such as `daily_today` and `daily_tomorrow` are
@@ -209,6 +208,10 @@ combinations, duplicate stanza names, and invalid options fail config loading.
`key_messages`, `short_term`, and `long_term`. Empty or omitted `sections` `key_messages`, `short_term`, and `long_term`. Empty or omitted `sections`
includes all available AFD sections. includes all available AFD sections.
The module registry accepts all module IDs documented in
[Module Contract Internals](internal/module.md). Modules without builders are
valid in composition but do not emit YAML stanzas.
## Secrets ## Secrets
Configuration files should not contain raw secrets. Use `secrets.directory` to Configuration files should not contain raw secrets. Use `secrets.directory` to
@@ -224,6 +227,6 @@ notification, this allows a file such as
- [examples/minimal-config.yml](../examples/minimal-config.yml): smallest - [examples/minimal-config.yml](../examples/minimal-config.yml): smallest
useful config for generation and fetching. useful config for generation and fetching.
- [examples/config.yml](../examples/config.yml): production-oriented config - [examples/config.yml](../examples/config.yml): production-oriented config
covering implemented fields. covering maintained fields.
Both example files are loaded by the config test suite. Both example files are loaded by the config test suite.

View File

@@ -6,7 +6,7 @@ This document describes the external Weather API contract used by
## Purpose ## Purpose
`weatherreporter` uses a configured Weather API base URL to fetch normalized `weatherreporter` uses a configured Weather API base URL to fetch normalized
weather source data and assemble a `forecast.Bundle`. This is an integration weather source data and assemble a `weatherdata.Bundle`. This is an integration
contract for the project adapter, not a complete public API reference for the contract for the project adapter, not a complete public API reference for the
upstream service. upstream service.
@@ -45,8 +45,7 @@ they fail the fetch; optional malformed sources follow the missing-source policy
The adapter sends these query parameters: The adapter sends these query parameters:
- `format`: from `weather_api.format`; the implemented configuration requires - `format`: from `weather_api.format`; configuration validation requires `json`
`json`
- `units`: from `weather_api.units` - `units`: from `weather_api.units`
- `precision`: from `weather_api.precision` on observations, current - `precision`: from `weather_api.precision` on observations, current
conditions, hourly forecast, and narrative forecast requests conditions, hourly forecast, and narrative forecast requests

View File

@@ -1,6 +1,6 @@
# App Orchestration Internals # App Orchestration Internals
This document describes the implemented workflow coordinator in `internal/app`. This document describes the workflow coordinator in `internal/app`.
## Purpose ## Purpose
@@ -26,9 +26,9 @@ Inputs:
Outputs: Outputs:
- generated report results with module snapshot, data package, preflight, report, - generated report results with JSON module snapshot, YAML data package,
metadata, prior snapshot, Recent Changes, Scriptorium result details, and preflight, report, metadata, prior snapshot, Recent Changes, Scriptorium
notification result when attempted result details, and notification result when attempted
- batch summaries with per-report status, artifact paths, error text, and - batch summaries with per-report status, artifact paths, error text, and
notification outcome when attempted notification outcome when attempted
- saved Weather API bundle JSON for fetch workflows - saved Weather API bundle JSON for fetch workflows

View File

@@ -1,49 +1,60 @@
# Module Builder Internals # Module Builder Internals
This document describes the implemented module builder boundary in This document describes module builder behavior in `internal/briefing`.
`internal/briefing`.
## Purpose ## Purpose
`internal/briefing` builds prompt-facing module values from resolved report `internal/briefing` turns report metadata, collected weather data, and derived
metadata, collected weather data, and derived forecast facts. These values are forecast facts into prompt-facing module outputs. The package also owns the
curated prompt inputs, not rendered report prose or durable report snapshots. module registry used to validate report composition and config overrides.
Module outputs are structured prompt inputs. They are not rendered report prose
and they are not persisted by this package.
## Inputs And Outputs ## Inputs And Outputs
Inputs: Inputs:
- resolved report definition, generation time, timezone, and valid period - resolved report definition, generation time, timezone, and valid period
- `weatherdata.Bundle` with source provenance and warnings - collected facts built from `weatherdata.Bundle`
- derived daily, period, or storm-window facts where required - derived daily, daypart, precipitation, alert, and storm-window facts where
required
- configured units, timezone, and descriptive location context - configured units, timezone, and descriptive location context
- typed module options from report defaults or config overrides
Outputs: Outputs:
- module registry definitions for known module IDs, stanza names, option - `ModuleDefinition` values with module ID, stanza name, option type,
shapes, fact requirements, report compatibility, and missing-data behavior supported reports, fact requirements, missing-data behavior, and builder
- source-oriented module outputs for `metadata`, `current_conditions`, - `module.Output` values for source-oriented stanzas:
`alert_digest`, `area_forecast_discussion`, and `weather_story` `metadata`, `current_conditions`, `alert_digest`,
- derived module outputs such as daily summaries, daypart summaries, `area_forecast_discussion`, and `weather_story`
precipitation timing, outdoor windows, and tomorrow planning - `module.Output` values for derived stanzas:
- optional current conditions and weather story module outputs when those `derived_daily_summary`, `derived_daypart_summaries`, `precip_timing`,
Weather API sources are available `outdoor_windows`, and `tomorrow_planning`
The registry also contains accepted composition entries for modules that do not
emit stanzas until a builder exists. App orchestration skips those entries when
constructing snapshots.
## Boundaries ## Boundaries
- This package selects and shapes weather facts for prompts. - This package selects and shapes already-collected weather facts for prompts.
- It owns module registry validation and module builder behavior. - It validates module composition against report compatibility and option
- It does not fetch weather data, compare prior snapshots, build types.
`data_package` files, invoke Scriptorium, or write workflow metadata. - It does not fetch weather data, compare prior snapshots, write module
snapshots, build YAML data packages, invoke Scriptorium, or write workflow
metadata.
## Config Fields Used ## Config Fields Used
The package receives configured units and timezone from the app layer. Daypart The app layer passes effective units, timezone, and location context into the
configuration is consumed by `internal/facts` before module builders run. module context. `internal/facts` consumes daypart configuration before module
Configured `location` values are prompt context only; Weather API builders run. Configured `location` values are prompt context only; Weather API
`sourceLocationId` and `sourceLocation` remain source provenance. `sourceLocationId` and `sourceLocation` remain source provenance.
Current conditions are copied from the normalized `/conditions/current` bundle
source only; observation station and timestamp fields remain provenance. `area_forecast_discussion` uses optional `sections` configuration to include a
subset of discussion fields.
## External Adapters Used ## External Adapters Used
@@ -51,13 +62,13 @@ None directly.
## State Or Manifest Behavior ## State Or Manifest Behavior
None. Module snapshots and prompt input data packages are persisted by None. `internal/app` collects module outputs into a `module.Snapshot`, and
`internal/state` and composed by `internal/app`. `internal/state` persists that snapshot.
## Skip And Resume Behavior ## Skip And Resume Behavior
None. Builders either return a module output, omit optional unavailable data, None. Builders either emit a module output, omit optional unavailable data, or
or return an error for invalid required inputs. return an error for invalid required inputs.
## Failure Behavior ## Failure Behavior
@@ -65,8 +76,9 @@ or return an error for invalid required inputs.
available. available.
- Module registry construction rejects duplicate module IDs and duplicate - Module registry construction rejects duplicate module IDs and duplicate
stanza names. stanza names.
- Module composition validation rejects unknown modules, duplicate modules, - Composition validation rejects unknown modules, duplicate modules,
incompatible report/module combinations, and invalid typed options. incompatible report/module combinations, duplicate stanza names, and invalid
option shapes.
- Source-oriented module builders omit missing optional current conditions, - Source-oriented module builders omit missing optional current conditions,
forecast discussion, and weather story stanzas. forecast discussion, and weather story stanzas.
- Alert digest output distinguishes checked empty alert data from missing alert - Alert digest output distinguishes checked empty alert data from missing alert
@@ -86,5 +98,4 @@ Inspect:
- Module outputs contain structured weather facts and source context. - Module outputs contain structured weather facts and source context.
- Common metadata includes RunID, report ID, prompt ID, valid period, source - Common metadata includes RunID, report ID, prompt ID, valid period, source
provenance, source hashes, source warnings, and configured prompt location. provenance, source hashes, source warnings, and configured prompt location.
- LLM prompt input packaging and Scriptorium execution remain outside this - Prompt input packaging and Scriptorium execution remain outside this package.
boundary.

View File

@@ -56,8 +56,7 @@ empty Recent Changes list without calling a comparison function.
`precip_timing` when present. `precip_timing` when present.
- 3-Day comparison requires `derived_daypart_summaries`. - 3-Day comparison requires `derived_daypart_summaries`.
- Weekend comparison requires `derived_daypart_summaries`. - Weekend comparison requires `derived_daypart_summaries`.
- Storm Report currently has no comparison implementation, so the app leaves - Storm Report comparison returns no changes.
Recent Changes empty for Storm reports.
## Tests ## Tests

View File

@@ -1,6 +1,6 @@
# Fact Contracts Internals # Fact Contracts Internals
This document describes the implemented fact contract boundary. This document describes the fact contract boundary.
## Purpose ## Purpose

View File

@@ -1,46 +1,90 @@
# Module Contract Internals # Module Contract Internals
This document describes the implemented module contract boundary. This document describes the module contract in `internal/module`.
## Purpose ## Purpose
`internal/module` defines stable module IDs, typed configuration items, module `internal/module` defines the shared identifiers and data envelopes used for
outputs, and module snapshots. It is a shared contract imported by report prompt-facing modules. Report definitions use module IDs for composition,
definitions and module registry code. module builders produce outputs with stanza names, prompt input packages consume
snapshots, and Recent Changes compares snapshot stanzas.
## Inputs And Outputs ## Inputs And Outputs
Inputs: Inputs:
- ordered `module.ConfigItem` values from report definitions - ordered `module.ConfigItem` values from report definitions or config
- `module.Output` values assembled by callers overrides
- `module.Output` values produced by module builders
Outputs: Outputs:
- stable `module.ID` constants - stable `module.ID` constants
- typed option structs for known modules - typed option structs for registered modules
- `module.Snapshot` with ordered outputs and schema version - `module.Snapshot` with schema version `weatherreporter.modules.v1`
- ordered snapshot outputs with module ID, stanza name, and typed value
- typed stanza lookup through `module.StanzaValue` - typed stanza lookup through `module.StanzaValue`
## Registered Module IDs
The registry recognizes these IDs:
- `metadata`
- `current_conditions`
- `derived_daily_summary`
- `derived_daypart_summaries`
- `hourly_table`
- `precip_timing`
- `alert_digest`
- `area_forecast_discussion`
- `weather_story`
- `forecast_delta`
- `outdoor_windows`
- `tomorrow_planning`
- `weekend_planning`
- `storm_window_summary`
Modules with builders emit stanzas into module snapshots. Registered modules
without builders are valid composition entries but do not emit snapshot stanzas.
That keeps report composition declarations centralized while limiting prompt
packages to data the application builds.
## Options
Most modules use an empty options struct. `area_forecast_discussion` accepts:
```yaml
sections:
- product
- key_messages
- short_term
- long_term
```
An omitted or empty `sections` list includes all available discussion sections.
Invalid option shapes fail during config normalization or composition
validation.
## Boundaries ## Boundaries
- This package owns shared module identifiers and output envelope contracts. - This package owns module identifiers, config item envelopes, output
- It does not define report IDs, build prompt stanzas, fetch weather data, envelopes, snapshot validation, and typed stanza lookup.
derive facts, write state, or invoke Scriptorium. - It does not define report IDs, execute builders, fetch weather data, derive
forecast facts, write state, or invoke Scriptorium.
## State Or Manifest Behavior ## State Or Manifest Behavior
`module.Snapshot` uses schema version `weatherreporter.modules.v1`. Snapshot `module.Snapshot` values are persisted by `internal/state` as JSON. Snapshot
validation rejects duplicate module outputs and duplicate stanza names while validation rejects missing schema version, missing module IDs, missing stanza
preserving output order. names, duplicate module outputs, and duplicate stanza names while preserving
output order.
## Failure Behavior ## Failure Behavior
- Snapshot validation fails when schema version, module ID, or stanza name is - Snapshot construction fails for duplicate module outputs or duplicate stanza
missing. names.
- Snapshot validation fails on duplicate module IDs or duplicate stanza names. - Typed stanza lookup returns `found=false` for missing stanzas.
- Typed stanza lookup returns `found=false` for missing stanzas and wraps JSON - Typed stanza lookup wraps JSON marshal/decode failures with stanza context.
marshal/decode failures with stanza context.
## Tests ## Tests
@@ -54,5 +98,5 @@ Inspect:
- `internal/module` does not import `internal/report`. - `internal/module` does not import `internal/report`.
- Module IDs are stable strings. - Module IDs are stable strings.
- Each module output has exactly one stanza name and one typed value. - Each emitted module output has exactly one stanza name and one typed value.
- Snapshot output order is caller-owned and preserved. - Snapshot output order is caller-owned and preserved.

View File

@@ -1,38 +1,63 @@
# Prompt Input Internals # Prompt Input Internals
This document describes prompt input data package construction. This document describes YAML prompt data package construction in
`internal/promptinput`.
## Purpose ## Purpose
`internal/promptinput` converts report metadata, module snapshots, and optional `internal/promptinput` converts report metadata, an ordered module snapshot,
Recent Changes into the YAML `data_package` passed to Scriptorium prompts. Recent Changes, and source warnings into the `data_package` file passed to
Scriptorium.
The persisted data package is YAML with schema version
`weatherreporter.data_package.v2`. It is separate from the JSON module snapshot
used for inspection and comparison.
## Inputs And Outputs ## Inputs And Outputs
Inputs: Inputs:
- report metadata - report metadata from app/state orchestration
- `module.Snapshot` - `module.Snapshot`
- optional `[]changes.Change` - optional `[]changes.Change`
Outputs: Outputs:
- `promptinput.Package` containing schema version, RunID, report metadata, - `promptinput.Package` with schema version, RunID, report metadata, named
named module stanzas under `briefing`, Recent Changes, and source warnings. module stanzas, Recent Changes, and source warnings
- report metadata includes `currentLocalDate`, the generation date formatted as - YAML bytes from `promptinput.MarshalYAML`
`YYYY-MM-DD` in the effective report timezone. - YAML file written atomically by `promptinput.Save`
- optional YAML file written by `promptinput.Save`
The YAML shape includes:
```yaml
schema_version: weatherreporter.data_package.v2
run_id: <run_id>
report:
id: <report_id>
prompt_id: <prompt_id>
briefing:
metadata: {}
current_conditions: {}
recent_changes:
items: []
```
The `briefing` mapping contains named module stanzas. Stanza order follows the
module snapshot output order.
## Boundaries ## Boundaries
- This package owns the prompt input schema and validation. - This package owns prompt package schema, YAML marshaling, YAML loading, and
- It does not fetch weather data, derive forecast summaries, find prior validation.
snapshots, compare changes, or invoke Scriptorium. - It does not fetch weather data, derive forecast summaries, execute modules,
find prior snapshots, compare changes, choose artifact paths, or invoke
Scriptorium.
## Config Fields Used ## Config Fields Used
None directly. Config-derived values, including timezone and prompt location None directly. Config-derived values such as timezone, units, and prompt
context, are already present in report metadata and module stanzas before this location are already present in report metadata and module stanzas before this
package runs. package runs.
## External Adapters Used ## External Adapters Used
@@ -51,8 +76,9 @@ None. Recent Changes is always present as an `items` list and may be empty.
## Failure Behavior ## Failure Behavior
Validation fails before render preflight when required top-level fields are Validation fails before render preflight when required top-level fields are
missing or inconsistent, or when no named module stanzas are present. Save missing or inconsistent, when the valid period is invalid, or when no module
failures include filesystem operation and path context. stanzas are present. Save failures include filesystem operation and path
context.
## Tests ## Tests
@@ -63,6 +89,7 @@ Inspect:
## Invariants ## Invariants
- Scriptorium receives structured `data_package` YAML. - Scriptorium receives structured YAML through `--input data_package=<path>`.
- Module stanza order is deterministic for generated snapshots. - Module stanza order is deterministic for generated snapshots.
- Recent Changes are not inferred from rendered report text. - Recent Changes are provided by `internal/changes`; this package does not
infer changes from rendered report text.

View File

@@ -7,8 +7,8 @@ membership, output naming, artifact grouping, and comparison declarations in
## Purpose ## Purpose
`internal/report` is the canonical source for report definitions. App, state, `internal/report` is the canonical source for report definitions. App, state,
module building, and CLI wiring consume resolved definitions instead of owning report module building, and CLI wiring consume resolved definitions instead of owning
identity policy themselves. report identity policy themselves.
## Definition Fields ## Definition Fields
@@ -25,7 +25,7 @@ Each report definition declares:
- morning or evening batch membership - morning or evening batch membership
- default ordered module composition - default ordered module composition
## Implemented Reports ## Reports
| Report | ID | Prompt | Artifact group | Batch copy | Prior compatibility | | Report | ID | Prompt | Artifact group | Batch copy | Prior compatibility |
| --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
@@ -35,7 +35,7 @@ Each report definition declares:
| Weekend Outlook | `weekend` | `weather.weekend_outlook` | `weekend` | `weekend.md` | Weekend Outlook | | Weekend Outlook | `weekend` | `weather.weekend_outlook` | `weekend` | `weekend.md` | Weekend Outlook |
| Storm Report | `storm` | `weather.storm_report` | `storm` | `storm.md` | Storm Report | | Storm Report | `storm` | `weather.storm_report` | `storm` | `storm.md` | Storm Report |
All implemented report definitions are eligible for generation. All report definitions are eligible for generation.
## Valid Periods ## Valid Periods
@@ -55,8 +55,8 @@ must be after start time.
## Boundaries ## Boundaries
`internal/report` defines report metadata and time coverage. It does not fetch `internal/report` defines report metadata and time coverage. It does not fetch
weather data, build module values, compare snapshot contents, write state, parse CLI weather data, build module values, compare snapshot contents, write state,
flags, or invoke Scriptorium. parse CLI flags, or invoke Scriptorium.
The CLI owns public command names. The app maps those command names to report The CLI owns public command names. The app maps those command names to report
IDs, then uses the registry for report policy. IDs, then uses the registry for report policy.

View File

@@ -84,8 +84,8 @@ current report definition.
date. date.
- Weekend Outlook compares with prior Weekend snapshots for the same weekend - Weekend Outlook compares with prior Weekend snapshots for the same weekend
window. window.
- Storm Report currently has no prior lookup because explicit event-window - Storm Report has no prior lookup because explicit event-window comparison is
comparison is not searched by the filesystem store. not searched by the filesystem store.
## Writes And Inspection ## Writes And Inspection

View File

@@ -1,12 +1,12 @@
# Weatherreporter Operations # Weatherreporter Operations
This guide covers normal operation, generated artifacts, inspection, recovery, This guide covers normal operation, generated artifacts, inspection, recovery,
and current operational caveats. For symptom-specific diagnosis, see and operational caveats. For symptom-specific diagnosis, see
[Troubleshooting](troubleshooting.md). [Troubleshooting](troubleshooting.md).
## Normal Workflow ## Normal Workflow
Implemented generation commands: Generation commands:
```text ```text
weatherreporter generate daily --date 2026-05-29 weatherreporter generate daily --date 2026-05-29
@@ -16,16 +16,16 @@ weatherreporter generate weekend
weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00 weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00
``` ```
Each command resolves a report period, fetches a Weather API bundle, builds Each command resolves a report period, fetches a Weather API bundle, builds a
module snapshots, builds a YAML prompt input data package, runs JSON module snapshot, builds a YAML prompt input data package, runs
`scriptorium render`, runs `scriptorium run`, and writes managed artifacts `scriptorium render`, runs `scriptorium run`, and writes managed artifacts under
under the configured workspace. the configured workspace.
When distributor notification is enabled, weatherreporter uploads the managed When distributor notification is enabled, weatherreporter uploads the managed
Markdown report after `scriptorium run` succeeds and final metadata is saved. Markdown report after `scriptorium run` succeeds and final metadata is saved.
`--out PATH` writes an extra Markdown copy for the current generated report; it `--out PATH` writes an extra Markdown copy for the current generated report; it
is not used as the distributor upload source. is not used as the distributor upload source.
Implemented batch commands: Batch commands:
```text ```text
weatherreporter run morning weatherreporter run morning
@@ -186,7 +186,7 @@ constructing a source bundle, and submitting it to the configured distributor
HTTP endpoint. Distributor remains responsible for destination routing, HTTP endpoint. Distributor remains responsible for destination routing,
publication, and any downstream Markdown-to-HTML transformation. Distributor publication, and any downstream Markdown-to-HTML transformation. Distributor
leaves destination files alone when they are not tracked by a newly uploaded leaves destination files alone when they are not tracked by a newly uploaded
bundle, so previously uploaded dated report paths can remain available. bundle, so existing uploaded dated report paths can remain available.
## Inspection ## Inspection
@@ -202,12 +202,12 @@ weatherreporter inspect prior RUN_ID
weatherreporter inspect sources RUN_ID weatherreporter inspect sources RUN_ID
``` ```
Use `inspect reports` to find recent RunIDs and artifact paths. Use Use `inspect reports` to find RunIDs and artifact paths. Use
`inspect metadata` to see the artifact links recorded for a run. Use `inspect metadata` to see the artifact links recorded for a run. Use
`inspect modules` to review the persisted ordered module snapshot, and `inspect modules` to review the persisted ordered module snapshot, and
`inspect data-package` to review the current structured prompt package used for `inspect data-package` to review the structured prompt package used for
rendering. Use `inspect prior` to see the prior comparable snapshot selected rendering. Use `inspect prior` to see the prior comparable snapshot selected for
for Recent Changes, or `null` when none exists. Use `inspect sources` to review Recent Changes, or `null` when none exists. Use `inspect sources` to review
source provenance and warnings without dumping full weather payloads. source provenance and warnings without dumping full weather payloads.
## Recent Changes ## Recent Changes
@@ -218,8 +218,8 @@ Markdown or YAML text.
Daily Today and Daily Tomorrow can compare with each other when they cover the Daily Today and Daily Tomorrow can compare with each other when they cover the
same valid local date. 3-Day Outlook compares with prior compatible 3-Day same valid local date. 3-Day Outlook compares with prior compatible 3-Day
snapshots for the same valid local date. Weekend Outlook compares with prior snapshots for the same valid local date. Weekend Outlook compares with prior
compatible Weekend snapshots for the same weekend window. Storm Report currently compatible Weekend snapshots for the same weekend window. Storm Report leaves
leaves Recent Changes empty. 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.