Compare recent changes from module snapshots

This commit is contained in:
2026-06-09 21:20:53 +00:00
parent 479d144592
commit 816cfb24aa
17 changed files with 508 additions and 346 deletions

View File

@@ -171,7 +171,7 @@ midday, afternoon, and evening.
- `wind_gust_miles_per_hour`: wind gust change threshold. Default: `10`.
- `precip_timing_shift_minutes`: precipitation timing shift threshold. Default: `120`.
Recent Changes are added to prompt input when a prior comparable briefing
Recent Changes are added to prompt input when a prior comparable module
snapshot exists and a threshold is crossed.
### `reports`

View File

@@ -70,19 +70,20 @@ Single-report generation follows this order:
2. Create or use a filesystem store.
3. Locate any prior compatible snapshot through `internal/state`.
4. Fetch a Weather API bundle.
5. Build a report-specific briefing package.
6. Save the briefing snapshot.
7. Compute Recent Changes from structured prior and current briefings.
8. Build and save the Scriptorium `data_package`.
9. Run Scriptorium render preflight.
10. Save preflight JSON when a render result is available.
11. Save metadata for inspection.
12. Run Scriptorium report generation to the managed report path.
13. Copy the managed report to the requested `--out` path when provided.
14. Save metadata with the managed report path.
15. If distributor notification is enabled, notify using the managed report
5. Build collected and derived facts once.
6. Execute configured modules and save the module snapshot.
7. Build and save the compatibility briefing snapshot.
8. Compute Recent Changes from structured prior and current module snapshots.
9. Build and save the YAML Scriptorium `data_package`.
10. Run Scriptorium render preflight.
11. Save preflight JSON when a render result is available.
12. Save metadata for inspection.
13. Run Scriptorium report generation to the managed report path.
14. Copy the managed report to the requested `--out` path when provided.
15. Save metadata with the managed report path.
16. If distributor notification is enabled, notify using the managed report
path as the source file.
16. Save a distributor notification debug artifact and update metadata with its
17. Save a distributor notification debug artifact and update metadata with its
path.
If render preflight returns both a result and an error, preflight JSON and
@@ -141,7 +142,7 @@ Inspect:
- Generated reports use the same app request and result types regardless of
report ID.
- Render preflight precedes Scriptorium report generation.
- Recent Changes are computed from structured briefing snapshots.
- Recent Changes are computed from structured module snapshots.
- Metadata links artifacts produced for a run.
- Distributor notification maps the managed Markdown report path to configured
bundle paths; extra output copies are not upload sources.

View File

@@ -4,15 +4,15 @@ This document describes structured Recent Changes comparison.
## Purpose
`internal/changes` compares current and prior briefing packages and emits
`internal/changes` compares current and prior module snapshots and emits
compact change records for prompt input data packages.
## Inputs And Outputs
Inputs:
- prior briefing package
- current briefing package
- prior module snapshot
- current module snapshot
- comparison thresholds from configuration
Outputs:
@@ -22,7 +22,7 @@ Outputs:
## Boundaries
- This package compares structured briefing data only.
- This package compares structured module snapshot data only.
- It does not read filesystem state, find prior snapshots, render Markdown,
invoke Scriptorium, or compare generated report text.
@@ -41,7 +41,7 @@ None.
## State Or Manifest Behavior
None directly. The app loads prior briefing snapshots through `internal/state`
None directly. The app loads prior module snapshots through `internal/state`
before calling comparison functions.
## Skip And Resume Behavior
@@ -51,9 +51,11 @@ empty Recent Changes list without calling a comparison function.
## Failure Behavior
- Daily comparison requires both inputs to contain Daily briefing content.
- 3-Day comparison requires both inputs to contain 3-Day briefing content.
- Weekend comparison requires both inputs to contain Weekend briefing content.
- Daily comparison requires `derived_daily_summary` and
`derived_daypart_summaries` stanzas. It also uses `alert_digest` and
`precip_timing` when present.
- 3-Day comparison requires `derived_daypart_summaries`.
- Weekend comparison requires `derived_daypart_summaries`.
- Storm Report currently has no comparison implementation, so the app leaves
Recent Changes empty for Storm reports.

View File

@@ -4,26 +4,24 @@ This document describes prompt input data package construction.
## Purpose
`internal/promptinput` converts a structured briefing package and optional
Recent Changes into the `data_package` JSON passed to Scriptorium prompts.
`internal/promptinput` converts report metadata, module snapshots, and optional
Recent Changes into the YAML `data_package` passed to Scriptorium prompts.
## Inputs And Outputs
Inputs:
- `briefing.Package`
- report metadata
- `module.Snapshot`
- optional `[]changes.Change`
Outputs:
- `promptinput.Package` containing schema version, RunID, report metadata,
briefing content, Recent Changes, and source warnings. Briefing content
includes configured location context, current conditions when available,
structured weather story context when available, discussion key messages, and
short/long-term AFD narratives when the Weather API provides them.
named briefing stanzas, Recent Changes, and source warnings.
- report metadata includes `currentLocalDate`, the generation date formatted as
`YYYY-MM-DD` in the effective report timezone.
- optional JSON file written by `promptinput.Save`
- optional YAML file written by `promptinput.Save`
## Boundaries
@@ -34,7 +32,8 @@ Outputs:
## Config Fields Used
None directly. Config-derived values, including timezone and prompt location
context, are already present in briefing metadata before this package runs.
context, are already present in report metadata and module stanzas before this
package runs.
## External Adapters Used
@@ -42,7 +41,7 @@ None.
## State Or Manifest Behavior
`promptinput.Save` writes JSON atomically. Managed workspace paths are owned by
`promptinput.Save` writes YAML atomically. Managed workspace paths are owned by
`internal/state`.
## Skip And Resume Behavior
@@ -51,9 +50,9 @@ None. Recent Changes is always present as an `items` list and may be empty.
## Failure Behavior
Validation fails before render preflight when required top-level or briefing
metadata fields are missing or inconsistent, or when no report content is
present. Save failures include filesystem operation and path context.
Validation fails before render preflight when required top-level fields are
missing or inconsistent, or when no named briefing stanzas are present. Save
failures include filesystem operation and path context.
## Tests
@@ -64,6 +63,6 @@ Inspect:
## Invariants
- Scriptorium receives structured `data_package` JSON.
- Briefing metadata and top-level report metadata must agree.
- Scriptorium receives structured `data_package` YAML.
- Module stanza order is deterministic for generated snapshots.
- Recent Changes are not inferred from rendered report text.

View File

@@ -216,8 +216,8 @@ source provenance and warnings without dumping full weather payloads.
## Recent Changes
Recent Changes are computed from structured briefing snapshots, not rendered
Markdown text.
Recent Changes are computed from structured module snapshots, not rendered
Markdown or YAML text.
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

View File

@@ -3,7 +3,7 @@
This document defines the development principles for this Go project. It is inward-facing: developers and LLM coding agents should use it to preserve the projects shape, boundaries, and invariants as the code evolves.
## weatherreporter
`weatherreporter` is a deterministic weather briefing and report-preparation application. It consumes normalized weather data from the internal weatherfeeder-backed API, derives report-specific briefing packages, compares those packages against prior snapshots, and invokes an external prompt runner to produce human-facing reports.
`weatherreporter` is a deterministic weather briefing and report-preparation application. It consumes normalized weather data from the internal weatherfeeder-backed API, derives report-specific module snapshots and prompt packages, compares module snapshots against prior runs, and invokes an external prompt runner to produce human-facing reports.
The application should keep meteorological data selection, daypart grouping, threshold detection, forecast-period resolution, and recent-change comparison inside Go domain packages. LLM prompts should receive curated briefing packages rather than raw unbounded source payloads wherever practical.