Finalized the initial development roadmap
This commit is contained in:
@@ -8,12 +8,12 @@ The application should remain a small, explicit, dependency-light Go program. Do
|
|||||||
|
|
||||||
`weatherreporter` is a deterministic weather briefing and report-preparation application. It should:
|
`weatherreporter` is a deterministic weather briefing and report-preparation application. It should:
|
||||||
|
|
||||||
1. Fetch normalized weather data from an internal weather API backed by `weatherfeeder`.
|
1. Fetch normalized weather data from a single configured internal weather API endpoint backed by `weatherfeeder`.
|
||||||
2. Derive report-specific briefing packages from the normalized forecast bundle.
|
2. Derive report-specific briefing packages from the normalized forecast bundle.
|
||||||
3. Compare current briefing snapshots against prior comparable snapshots to produce optional Recent Changes.
|
3. Compare current briefing snapshots against prior comparable snapshots to produce optional Recent Changes.
|
||||||
4. Build structured prompt variables for a specific report type.
|
4. Build structured prompt input data packages for a specific report type.
|
||||||
5. Invoke `scriptorium` as an external prompt runner.
|
5. Invoke `scriptorium` as an external prompt runner.
|
||||||
6. Persist the rendered Markdown report, briefing snapshot, and generation metadata.
|
6. Persist the rendered Markdown report, briefing snapshot, prompt input package, and generation metadata.
|
||||||
|
|
||||||
The preferred data flow is:
|
The preferred data flow is:
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ weatherfeeder-backed internal API
|
|||||||
-> forecast bundle
|
-> forecast bundle
|
||||||
-> report-specific briefing builder
|
-> report-specific briefing builder
|
||||||
-> recent-change comparison
|
-> recent-change comparison
|
||||||
-> prompt variable package
|
-> prompt input data package
|
||||||
-> scriptorium subprocess adapter
|
-> scriptorium subprocess adapter
|
||||||
-> Markdown report + metadata + stored snapshot
|
-> Markdown report + metadata + stored snapshot
|
||||||
```
|
```
|
||||||
@@ -96,7 +96,7 @@ internal/state/
|
|||||||
filesystem.go
|
filesystem.go
|
||||||
metadata.go
|
metadata.go
|
||||||
|
|
||||||
internal/promptvars/
|
internal/promptinput/
|
||||||
build.go
|
build.go
|
||||||
schema.go
|
schema.go
|
||||||
|
|
||||||
@@ -167,7 +167,8 @@ Responsibilities:
|
|||||||
- `weatherreporter run morning`
|
- `weatherreporter run morning`
|
||||||
- `weatherreporter run evening`
|
- `weatherreporter run evening`
|
||||||
- `weatherreporter inspect snapshot`
|
- `weatherreporter inspect snapshot`
|
||||||
- Parse CLI flags and convert them into app-layer request structs.
|
- Use the Go standard library for CLI parsing unless future complexity justifies a dependency.
|
||||||
|
- Parse flags such as `--config`, `--units`, `--tz`, `--out`, optional Daily `--date`, and storm `--start`/`--end`, then convert them into app-layer request structs.
|
||||||
- Load configuration through `internal/config`.
|
- Load configuration through `internal/config`.
|
||||||
- Present concise user-facing errors.
|
- Present concise user-facing errors.
|
||||||
|
|
||||||
@@ -181,15 +182,19 @@ Non-responsibilities:
|
|||||||
Suggested command shape:
|
Suggested command shape:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
weatherreporter generate daily --location home --date today --out ./daily.md
|
weatherreporter generate daily --date 2026-05-29 --out ./daily.md
|
||||||
weatherreporter generate tomorrow --location home --out ./tomorrow.md
|
weatherreporter generate tomorrow --out ./tomorrow.md
|
||||||
weatherreporter generate three-day --location home --out ./three_day.md
|
weatherreporter generate three-day --out ./three_day.md
|
||||||
weatherreporter generate weekend --location home --out ./weekend.md
|
weatherreporter generate weekend --out ./weekend.md
|
||||||
weatherreporter generate storm --location home --out ./storm.md
|
weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00 --out ./storm.md
|
||||||
weatherreporter run morning --location home
|
weatherreporter run morning
|
||||||
weatherreporter run evening --location home
|
weatherreporter run evening
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The MVP should not expose location selection. Source `locationId` and `locationName` values returned by the weather API may be retained as provenance.
|
||||||
|
|
||||||
|
For `generate daily`, `--date` is optional. When provided, it must use `YYYY-MM-DD`; when omitted, it resolves to the current local date in the configured timezone.
|
||||||
|
|
||||||
### `internal/config`
|
### `internal/config`
|
||||||
|
|
||||||
Owns configuration structures, defaults, loading, precedence, and validation.
|
Owns configuration structures, defaults, loading, precedence, and validation.
|
||||||
@@ -199,20 +204,29 @@ Responsibilities:
|
|||||||
- Define application configuration structs.
|
- Define application configuration structs.
|
||||||
- Provide built-in defaults in `defaults.go`.
|
- Provide built-in defaults in `defaults.go`.
|
||||||
- Load YAML configuration from `/usr/local/etc/weatherreporter/config.yml` or a CLI-supplied path.
|
- Load YAML configuration from `/usr/local/etc/weatherreporter/config.yml` or a CLI-supplied path.
|
||||||
|
- Use `gopkg.in/yaml.v3` for YAML parsing.
|
||||||
- Apply precedence rules.
|
- Apply precedence rules.
|
||||||
- Validate required settings.
|
- Validate required settings.
|
||||||
- Normalize paths, durations, report settings, locations, and daypart definitions.
|
- Normalize paths, durations, report settings, weather API units/timezone, missing-source policy, and daypart definitions.
|
||||||
|
|
||||||
Suggested configuration areas:
|
Suggested configuration areas:
|
||||||
|
|
||||||
- Weather API base URL, timeout, and location endpoints.
|
- Weather API base URL, timeout, units, timezone, precision, and missing-source policy.
|
||||||
- Locations and time zones.
|
- `scriptorium` binary, config path, profile, timeout, and optional extra arguments.
|
||||||
- `scriptorium` binary, profile, timeout, and optional extra arguments.
|
|
||||||
- Workspace and output directories.
|
- Workspace and output directories.
|
||||||
- Report enablement and output naming.
|
- Report enablement and output naming.
|
||||||
- Daypart definitions.
|
- Daypart definitions.
|
||||||
- Recent-change thresholds.
|
- Recent-change thresholds.
|
||||||
|
|
||||||
|
Initial defaults:
|
||||||
|
|
||||||
|
- Weather API units: `us`.
|
||||||
|
- Weather API timezone: `Chicago`.
|
||||||
|
- Weather API format: `json`.
|
||||||
|
- Missing-source policy: `warn`.
|
||||||
|
|
||||||
|
Missing-source policy should support a global default and per-source overrides. Valid policy values are `error`, `warn`, and `none`.
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
|
|
||||||
- No command execution.
|
- No command execution.
|
||||||
@@ -230,7 +244,7 @@ Responsibilities:
|
|||||||
- Run the morning batch.
|
- Run the morning batch.
|
||||||
- Run the evening batch.
|
- Run the evening batch.
|
||||||
- Generate a manual storm report.
|
- Generate a manual storm report.
|
||||||
- Coordinate config, weather API adapter, report registry, briefing builders, state store, change comparison, prompt variable builder, and `scriptorium` runner.
|
- Coordinate config, weather API adapter, report registry, briefing builders, state store, change comparison, prompt input builder, and `scriptorium` runner.
|
||||||
- Enforce workflow order.
|
- Enforce workflow order.
|
||||||
- Ensure each generation run persists enough artifacts for inspection and future comparison.
|
- Ensure each generation run persists enough artifacts for inspection and future comparison.
|
||||||
|
|
||||||
@@ -238,15 +252,16 @@ The core generation workflow should be approximately:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
resolve report definition
|
resolve report definition
|
||||||
resolve location and valid period
|
resolve valid period
|
||||||
fetch current weather bundle
|
fetch current weather bundle
|
||||||
build current briefing package
|
build current briefing package
|
||||||
load prior comparable briefing snapshot
|
load prior comparable briefing snapshot
|
||||||
compute recent changes
|
compute recent changes
|
||||||
build prompt variables
|
build prompt input data package
|
||||||
write vars file
|
write data package
|
||||||
invoke scriptorium
|
run scriptorium render preflight
|
||||||
persist report metadata and briefing snapshot
|
invoke scriptorium run
|
||||||
|
persist report metadata, briefing snapshot, data package, preflight output, and rendered report
|
||||||
```
|
```
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
@@ -261,25 +276,37 @@ HTTP adapter for the internal weather API backed by `weatherfeeder`.
|
|||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
- Fetch normalized weather data for a configured location.
|
- Fetch normalized weather data from the configured API base URL.
|
||||||
|
- Fan out to multiple weather API endpoints and assemble one internal `forecast.Bundle`.
|
||||||
- Decode API responses into adapter-owned DTOs or directly into stable internal types if those types are intentionally owned by `weatherreporter`.
|
- Decode API responses into adapter-owned DTOs or directly into stable internal types if those types are intentionally owned by `weatherreporter`.
|
||||||
- Apply request timeouts and context cancellation.
|
- Apply request timeouts and context cancellation.
|
||||||
|
- Apply configured query defaults, including `format=json`, `units=us`, and `tz=Chicago` unless overridden.
|
||||||
|
- Fetch full `/forecast/hourly` and `/forecast/narrative` products, not day-slice endpoints, so Go domain code owns report-period selection.
|
||||||
|
- Record per-source provenance: endpoint, query, fetch time, issued/updated time when available, SHA-256 over canonical/minified raw `data` JSON, warnings, and missing-source status.
|
||||||
|
- Represent source warnings as first-class records with source name, code, severity, message, endpoint, and completeness impact.
|
||||||
|
- Require hourly forecast data for normal scheduled reports.
|
||||||
|
- Apply missing-source policy for `data:null`, malformed non-required sections, or unavailable upstream products.
|
||||||
- Return actionable errors containing endpoint and operation context.
|
- Return actionable errors containing endpoint and operation context.
|
||||||
|
|
||||||
Expected data categories:
|
Initial data categories:
|
||||||
|
|
||||||
|
- Latest observation.
|
||||||
|
- Current conditions.
|
||||||
- Hourly forecast data.
|
- Hourly forecast data.
|
||||||
- Daily forecast data.
|
|
||||||
- NWS narrative forecast periods.
|
- NWS narrative forecast periods.
|
||||||
- NWS alerts.
|
- NWS alerts.
|
||||||
- NWS forecast discussion.
|
- NWS forecast discussion.
|
||||||
|
|
||||||
|
Stubbed source slots until upstream support exists:
|
||||||
|
|
||||||
|
- Daily forecast data.
|
||||||
- NWS weather story.
|
- NWS weather story.
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
|
|
||||||
- No daypart grouping.
|
- No daypart grouping.
|
||||||
- No Recent Changes comparison.
|
- No Recent Changes comparison.
|
||||||
- No prompt variable construction.
|
- No prompt input construction.
|
||||||
- No `scriptorium` calls.
|
- No `scriptorium` calls.
|
||||||
|
|
||||||
### `internal/adapters/scriptorium`
|
### `internal/adapters/scriptorium`
|
||||||
@@ -292,24 +319,32 @@ Responsibilities:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type Runner interface {
|
type Runner interface {
|
||||||
|
Render(ctx context.Context, req RenderRequest) (*RenderResult, error)
|
||||||
Run(ctx context.Context, req RunRequest) (*RunResult, error)
|
Run(ctx context.Context, req RunRequest) (*RunResult, error)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- Execute `scriptorium run` with `exec.CommandContext`.
|
- Execute `scriptorium render` for preflight/debug output without LLM generation.
|
||||||
|
- Execute `scriptorium run` for report generation.
|
||||||
|
- Run `scriptorium render` as an always-on preflight before `scriptorium run` for MVP generated reports.
|
||||||
- Pass arguments as an argv slice, not through a shell.
|
- Pass arguments as an argv slice, not through a shell.
|
||||||
- Prefer a vars file path over large inline JSON.
|
- Pass large prompt input as `--input data_package=<path>`.
|
||||||
- Capture stdout/stderr with reasonable size limits.
|
- Capture stdout/stderr with reasonable size limits.
|
||||||
- Treat nonzero exits as actionable errors.
|
- Treat nonzero exits as actionable errors, including exit code `2` from `run`, which may still produce output.
|
||||||
- Keep all `scriptorium`-specific flag details inside the adapter.
|
- Keep all `scriptorium`-specific flag details inside the adapter.
|
||||||
|
|
||||||
Suggested command form:
|
Suggested command forms:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
scriptorium render \
|
||||||
|
--prompt weather.daily_report \
|
||||||
|
--input data_package=./workspace/data-packages/daily/2026-05-29T050000-0500.data_package.json \
|
||||||
|
--format json
|
||||||
|
|
||||||
scriptorium run \
|
scriptorium run \
|
||||||
--prompt weather.daily_report \
|
--prompt weather.daily_report \
|
||||||
--vars-file ./workspace/daily.vars.json \
|
--input data_package=./workspace/data-packages/daily/2026-05-29T050000-0500.data_package.json \
|
||||||
--out ./workspace/daily_report.md
|
--out ./workspace/reports/daily/2026-05-29T050000-0500.md
|
||||||
```
|
```
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
@@ -365,12 +400,14 @@ Suggested report definitions:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
daily_today -> prompt weather.daily_report
|
daily_today -> prompt weather.daily_report
|
||||||
daily_tomorrow -> prompt weather.daily_report or weather.tomorrow_report
|
daily_tomorrow -> prompt weather.daily_report
|
||||||
three_day -> prompt weather.three_day_outlook
|
three_day -> prompt weather.three_day_outlook
|
||||||
weekend -> prompt weather.weekend_outlook
|
weekend -> prompt weather.weekend_outlook
|
||||||
storm -> prompt weather.storm_report
|
storm -> prompt weather.storm_report
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`weather.daily_report` should be the standard prompt for one local civil day, regardless of whether that day is today or tomorrow.
|
||||||
|
|
||||||
A report definition should describe:
|
A report definition should describe:
|
||||||
|
|
||||||
- Report ID.
|
- Report ID.
|
||||||
@@ -395,9 +432,10 @@ Builds report-specific briefing packages from forecast bundles and report defini
|
|||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
- Convert a forecast bundle into a report-specific structured briefing package.
|
- Convert a forecast bundle into a report-specific structured briefing package.
|
||||||
- Keep each report’s briefing shape explicit and testable.
|
- Keep each report's briefing shape explicit and testable.
|
||||||
- Attach relevant NWS narrative periods, alerts, forecast discussion context, and weather story context.
|
- Attach relevant NWS narrative periods, alerts, forecast discussion context, and weather story context when available.
|
||||||
- Provide inputs suitable for LLM prompt variables.
|
- Include metadata such as schema version, configured units/timezone, source warnings, and source provenance.
|
||||||
|
- Provide inputs suitable for `scriptorium` data packages.
|
||||||
|
|
||||||
Report-specific builders should exist for:
|
Report-specific builders should exist for:
|
||||||
|
|
||||||
@@ -425,9 +463,11 @@ Responsibilities:
|
|||||||
|
|
||||||
- Compare current briefing packages against prior comparable snapshots.
|
- Compare current briefing packages against prior comparable snapshots.
|
||||||
- Apply meaningful-change thresholds.
|
- Apply meaningful-change thresholds.
|
||||||
- Produce compact structured change summaries for prompt variables.
|
- Produce compact structured change summaries for prompt input data packages.
|
||||||
- Avoid comparison of rendered Markdown report text.
|
- Avoid comparison of rendered Markdown report text.
|
||||||
|
|
||||||
|
Comparable snapshot matching should be declared by each report definition. Daily Today, Daily Tomorrow, and compatible date slices from multi-day reports may compare by same valid local date when the report registry marks them compatible. Weekend compares by same weekend window. Storm compares by explicit event window.
|
||||||
|
|
||||||
Meaningful changes may include:
|
Meaningful changes may include:
|
||||||
|
|
||||||
- Temperature changes crossing configured thresholds.
|
- Temperature changes crossing configured thresholds.
|
||||||
@@ -447,14 +487,17 @@ Non-responsibilities:
|
|||||||
|
|
||||||
### `internal/state`
|
### `internal/state`
|
||||||
|
|
||||||
Durable state store for reports, snapshots, metadata, and comparison lookup.
|
Durable state store for reports, snapshots, data packages, preflight output, metadata, and comparison lookup.
|
||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
- Persist generated report metadata.
|
- Persist generated report metadata.
|
||||||
- Persist briefing snapshots.
|
- Persist briefing snapshots.
|
||||||
- Persist prompt variable files when useful for inspection.
|
- Persist prompt input data packages.
|
||||||
|
- Persist `scriptorium render` preflight output for generated reports.
|
||||||
- Locate prior comparable snapshots for Recent Changes.
|
- Locate prior comparable snapshots for Recent Changes.
|
||||||
|
- Track RunID as generation timestamp plus report ID.
|
||||||
|
- Use timestamped managed report names to avoid overwriting prior runs for the same valid period.
|
||||||
- Use atomic writes where practical.
|
- Use atomic writes where practical.
|
||||||
- Keep filesystem layout narrow and predictable.
|
- Keep filesystem layout narrow and predictable.
|
||||||
|
|
||||||
@@ -470,8 +513,6 @@ Suggested state layout:
|
|||||||
|
|
||||||
```text
|
```text
|
||||||
workspace/
|
workspace/
|
||||||
locations/
|
|
||||||
home/
|
|
||||||
snapshots/
|
snapshots/
|
||||||
daily/
|
daily/
|
||||||
2026-05-30/
|
2026-05-30/
|
||||||
@@ -482,13 +523,16 @@ workspace/
|
|||||||
storm/
|
storm/
|
||||||
reports/
|
reports/
|
||||||
daily/
|
daily/
|
||||||
2026-05-30.md
|
2026-05-29T050000-0500.md
|
||||||
three-day/
|
three-day/
|
||||||
weekend/
|
weekend/
|
||||||
storm/
|
storm/
|
||||||
vars/
|
data-packages/
|
||||||
daily/
|
daily/
|
||||||
2026-05-29T050000-0500.vars.json
|
2026-05-29T050000-0500.data_package.json
|
||||||
|
preflight/
|
||||||
|
daily/
|
||||||
|
2026-05-29T050000-0500.render.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
@@ -497,16 +541,16 @@ Non-responsibilities:
|
|||||||
- No report prose generation.
|
- No report prose generation.
|
||||||
- No CLI formatting decisions.
|
- No CLI formatting decisions.
|
||||||
|
|
||||||
### `internal/promptvars`
|
### `internal/promptinput`
|
||||||
|
|
||||||
Builds the final variable payload passed to `scriptorium`.
|
Builds the final data package passed to `scriptorium`.
|
||||||
|
|
||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
- Combine report metadata, briefing package, Recent Changes, and selected source context into a prompt variable document.
|
- Combine report metadata, briefing package, Recent Changes, selected source context, and source warnings into a prompt input document.
|
||||||
- Validate required prompt variables before invoking `scriptorium`.
|
- Validate required data package fields before invoking `scriptorium`.
|
||||||
- Keep prompt variable schemas explicit enough to test.
|
- Keep data package schemas explicit enough to test.
|
||||||
- Write vars files to the workspace when requested by the app layer.
|
- Write data package files to the workspace when requested by the app layer.
|
||||||
|
|
||||||
Non-responsibilities:
|
Non-responsibilities:
|
||||||
|
|
||||||
@@ -521,7 +565,7 @@ Time, clock, and period helpers.
|
|||||||
Responsibilities:
|
Responsibilities:
|
||||||
|
|
||||||
- Provide an injectable clock for deterministic tests.
|
- Provide an injectable clock for deterministic tests.
|
||||||
- Resolve local dates using the configured location time zone.
|
- Resolve local dates using the configured report timezone.
|
||||||
- Handle daypart spans, including overnight windows.
|
- Handle daypart spans, including overnight windows.
|
||||||
- Normalize valid periods.
|
- Normalize valid periods.
|
||||||
- Provide helpers for recurring scheduled batches.
|
- Provide helpers for recurring scheduled batches.
|
||||||
@@ -535,24 +579,38 @@ Non-responsibilities:
|
|||||||
|
|
||||||
Each generated report must be associated with explicit metadata:
|
Each generated report must be associated with explicit metadata:
|
||||||
|
|
||||||
|
- RunID.
|
||||||
- Report type.
|
- Report type.
|
||||||
- Report variant, if applicable.
|
- Report variant, if applicable.
|
||||||
- Location ID.
|
|
||||||
- Generation time.
|
- Generation time.
|
||||||
|
- Configured report timezone.
|
||||||
- Valid period start.
|
- Valid period start.
|
||||||
- Valid period end.
|
- Valid period end.
|
||||||
- Source product timestamps and/or hashes.
|
- Source location ID/name when provided by upstream.
|
||||||
|
- Source product timestamps and/or SHA-256 hashes.
|
||||||
|
- Source warnings.
|
||||||
- Briefing snapshot path.
|
- Briefing snapshot path.
|
||||||
- Prompt variable path.
|
- Prompt input data package path.
|
||||||
|
- Preflight output path.
|
||||||
- Rendered report path.
|
- Rendered report path.
|
||||||
|
|
||||||
|
All valid periods should use the configured local timezone, default `Chicago`, and half-open `[start,end)` intervals.
|
||||||
|
|
||||||
|
Initial valid-period rules:
|
||||||
|
|
||||||
|
- Daily Today: current local civil day, `[00:00, next 00:00)`.
|
||||||
|
- Daily Tomorrow: next local civil day.
|
||||||
|
- 3-Day Outlook: generation time through local midnight after the second following local civil day.
|
||||||
|
- Weekend Outlook: Monday through Thursday covers Saturday 00:00 to Monday 00:00; Friday and Saturday cover `max(generation time, Friday 18:00)` to Monday 00:00; scheduled Sunday morning skips Weekend Outlook.
|
||||||
|
- Manual Storm Report: requires explicit `--start` and `--end`; accept `YYYY-MM-DDTHH:MM` interpreted in the configured timezone and RFC3339 timestamps with explicit offsets.
|
||||||
|
|
||||||
The valid period should identify what weather period the report covers, independent of when the report was generated.
|
The valid period should identify what weather period the report covers, independent of when the report was generated.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
- A 5 PM Tomorrow Planning Brief for Saturday and a 5 AM Saturday Daily Report both cover the same valid date.
|
- A 5 PM Tomorrow Planning Brief for Saturday and a 5 AM Saturday Daily Report both cover the same valid date.
|
||||||
- A Saturday Weekend Outlook covers the remaining weekend, while a Friday Weekend Outlook may cover Friday evening through Sunday night.
|
- A Saturday Weekend Outlook covers the remaining weekend, while a Friday Weekend Outlook may cover Friday evening through Sunday night.
|
||||||
- A Storm Report covers a forecast event window, not a fixed calendar day.
|
- A Storm Report covers an explicit forecast event window, not a fixed calendar day.
|
||||||
|
|
||||||
This identity is required for reliable Recent Changes behavior.
|
This identity is required for reliable Recent Changes behavior.
|
||||||
|
|
||||||
@@ -572,6 +630,8 @@ evening:
|
|||||||
- daily_tomorrow
|
- daily_tomorrow
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Scheduled batches should continue independent reports after a report failure. The CLI should return nonzero if any report failed and should emit an aggregate run summary.
|
||||||
|
|
||||||
External scheduling should be handled by systemd timers, cron, or another orchestrator. `weatherreporter` should simply provide deterministic commands that can be scheduled.
|
External scheduling should be handled by systemd timers, cron, or another orchestrator. `weatherreporter` should simply provide deterministic commands that can be scheduled.
|
||||||
|
|
||||||
## Storm Report Direction
|
## Storm Report Direction
|
||||||
@@ -579,7 +639,7 @@ External scheduling should be handled by systemd timers, cron, or another orches
|
|||||||
The initial version should support manual Storm Report generation:
|
The initial version should support manual Storm Report generation:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
weatherreporter generate storm --location home
|
weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00
|
||||||
```
|
```
|
||||||
|
|
||||||
Future storm monitoring should use a staged design:
|
Future storm monitoring should use a staged design:
|
||||||
@@ -606,14 +666,16 @@ Core tests should not require real external services.
|
|||||||
|
|
||||||
Priority test areas:
|
Priority test areas:
|
||||||
|
|
||||||
- Configuration loading and validation.
|
- Configuration loading and validation, including defaults for `units=us`, `tz=Chicago`, and missing-source policy `warn`.
|
||||||
|
- Standard-library CLI command parsing, including `--units`, `--tz`, and storm `--start`/`--end`.
|
||||||
|
- Weather API fan-out, source provenance, `data:null`, and missing-source policy behavior.
|
||||||
- Daypart grouping, especially overnight periods.
|
- Daypart grouping, especially overnight periods.
|
||||||
- Valid-period resolution for each report type.
|
- Valid-period resolution for each report type.
|
||||||
- Briefing package construction from fixtures.
|
- Briefing package construction from fixtures.
|
||||||
- Recent Changes threshold behavior.
|
- Recent Changes threshold behavior and compatible snapshot matching.
|
||||||
- Prior snapshot lookup.
|
- Prior snapshot lookup.
|
||||||
- `scriptorium` adapter behavior using a fake executable or command runner.
|
- `scriptorium` adapter behavior using a fake executable or command runner, including both `render` and `run` with `--input data_package=<path>`.
|
||||||
- CLI command parsing for major workflows.
|
- Batch partial-failure behavior and aggregate exit status.
|
||||||
|
|
||||||
## Design Invariants
|
## Design Invariants
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,26 @@ The goal is to build the application in stable layers. Each stage should leave t
|
|||||||
## Guiding Implementation Principles
|
## Guiding Implementation Principles
|
||||||
|
|
||||||
- Build deterministic data preparation before LLM rendering.
|
- Build deterministic data preparation before LLM rendering.
|
||||||
- Keep CLI, adapters, domain logic, state, and prompt-variable construction separate.
|
- Keep CLI, adapters, domain logic, state, and prompt input construction separate.
|
||||||
- Use fixture-driven tests for forecast processing and briefing builders.
|
- Use fixture-driven tests for forecast processing and briefing builders.
|
||||||
- Persist intermediate artifacts so failed or low-quality reports can be inspected.
|
- Persist intermediate artifacts so failed or low-quality reports can be inspected.
|
||||||
- Add one report type fully before generalizing to all report types.
|
- Add one report type fully before generalizing to all report types.
|
||||||
- Treat `scriptorium` as an external adapter during the prototype.
|
- Treat `scriptorium` as an external adapter during the prototype.
|
||||||
- Do not build the storm-monitoring agent until scheduled report generation is reliable.
|
- Do not build the storm-monitoring agent until scheduled report generation is reliable.
|
||||||
|
- Do not support multiple weatherreporter locations in the MVP; use one configured Weather API endpoint.
|
||||||
|
|
||||||
|
## MVP Decisions Locked
|
||||||
|
|
||||||
|
- Use one configured Weather API endpoint; do not expose MVP location selection.
|
||||||
|
- Use the Go standard library for CLI parsing.
|
||||||
|
- Use `gopkg.in/yaml.v3` for YAML configuration.
|
||||||
|
- Default Weather API query values are `format=json`, `units=us`, and `tz=Chicago`.
|
||||||
|
- Default missing-source policy is `warn`.
|
||||||
|
- Fetch full `/forecast/hourly` and `/forecast/narrative` products; Go owns report-period selection.
|
||||||
|
- Require hourly forecast data for normal scheduled reports.
|
||||||
|
- Use `scriptorium render` as an always-on preflight before `scriptorium run` for generated reports.
|
||||||
|
- Pass prompt input to `scriptorium` with `--input data_package=<path>`.
|
||||||
|
- Identify source payloads with SHA-256 over canonical/minified raw `data` JSON.
|
||||||
|
|
||||||
## Stage 0: Repository Skeleton and Architecture Baseline
|
## Stage 0: Repository Skeleton and Architecture Baseline
|
||||||
|
|
||||||
@@ -35,7 +49,7 @@ Create the project skeleton, commit the architecture documents, and establish th
|
|||||||
4. Add this implementation roadmap.
|
4. Add this implementation roadmap.
|
||||||
5. Create minimal package directories and placeholder files where useful.
|
5. Create minimal package directories and placeholder files where useful.
|
||||||
6. Add basic build/test tooling.
|
6. Add basic build/test tooling.
|
||||||
7. Add a minimal `weatherreporter --help` command.
|
7. Add a minimal `weatherreporter --help` command using the Go standard library.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
@@ -66,20 +80,24 @@ Implement configuration loading and a stable command shape before integrating ex
|
|||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Define configuration structs for:
|
1. Define configuration structs for:
|
||||||
- Weather API settings.
|
- Weather API base URL, timeout, precision, units, and timezone.
|
||||||
- Locations.
|
- Missing-source behavior, with a global default and optional per-source overrides.
|
||||||
- Location time zones.
|
|
||||||
- `scriptorium` settings.
|
- `scriptorium` settings.
|
||||||
- Workspace paths.
|
- Workspace paths.
|
||||||
- Report output paths.
|
- Report output paths.
|
||||||
- Daypart definitions.
|
- Daypart definitions.
|
||||||
- Recent-change thresholds.
|
- Recent-change thresholds.
|
||||||
2. Implement built-in defaults in `internal/config/defaults.go`.
|
2. Implement built-in defaults in `internal/config/defaults.go`:
|
||||||
|
- `units=us`
|
||||||
|
- `tz=Chicago`
|
||||||
|
- `format=json`
|
||||||
|
- missing-source policy `warn`
|
||||||
3. Implement YAML config loading from:
|
3. Implement YAML config loading from:
|
||||||
- `/usr/local/etc/weatherreporter/config.yml`
|
- `/usr/local/etc/weatherreporter/config.yml`
|
||||||
- CLI override via `--config`
|
- CLI override via `--config`
|
||||||
4. Implement config validation.
|
4. Use `gopkg.in/yaml.v3` for YAML parsing.
|
||||||
5. Implement basic command structure:
|
5. Implement config validation.
|
||||||
|
6. Implement basic command structure with the Go standard library:
|
||||||
- `generate daily`
|
- `generate daily`
|
||||||
- `generate tomorrow`
|
- `generate tomorrow`
|
||||||
- `generate three-day`
|
- `generate three-day`
|
||||||
@@ -87,27 +105,35 @@ Implement configuration loading and a stable command shape before integrating ex
|
|||||||
- `generate storm`
|
- `generate storm`
|
||||||
- `run morning`
|
- `run morning`
|
||||||
- `run evening`
|
- `run evening`
|
||||||
6. Commands may initially return “not implemented” after config and request resolution.
|
7. Add CLI flag parsing for:
|
||||||
7. Add time-zone and clock helpers.
|
- `--config`
|
||||||
|
- `--units`
|
||||||
|
- `--tz`
|
||||||
|
- `--out`
|
||||||
|
- optional `--date` for Daily Today, accepting `YYYY-MM-DD` and defaulting to the current local date in the configured timezone
|
||||||
|
- `--start` and `--end` for manual Storm Reports
|
||||||
|
8. Commands may initially return "not implemented" after config and request resolution.
|
||||||
|
9. Add time-zone and clock helpers.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- Config can be loaded, validated, and inspected in tests.
|
- Config can be loaded, validated, and inspected in tests.
|
||||||
- CLI commands parse expected flags.
|
- CLI commands parse expected flags without a CLI framework dependency.
|
||||||
- App-layer request structs exist for report generation and scheduled batches.
|
- App-layer request structs exist for report generation and scheduled batches.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Config defaults load successfully.
|
- Config defaults load successfully, including `units=us`, `tz=Chicago`, and missing-source policy `warn`.
|
||||||
- Example config file load test.
|
- Example config file load test.
|
||||||
- Invalid config produces actionable errors.
|
- Invalid config produces actionable errors.
|
||||||
- CLI parser tests for major commands.
|
- CLI parser tests for major commands and shared flags.
|
||||||
|
- Storm `--start`/`--end` parsing tests.
|
||||||
- Time-zone resolution tests.
|
- Time-zone resolution tests.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- CLI request handling is stable enough that later stages can attach real behavior without reshaping commands.
|
- CLI request handling is stable enough that later stages can attach real behavior without reshaping commands.
|
||||||
- Configuration can represent at least one location and the default daypart set.
|
- Configuration can represent the single Weather API endpoint, default units/timezone, default daypart set, and missing-source policy.
|
||||||
|
|
||||||
## Stage 2: Weather API Adapter and Forecast Bundle
|
## Stage 2: Weather API Adapter and Forecast Bundle
|
||||||
|
|
||||||
@@ -117,8 +143,8 @@ Fetch normalized weather data from the internal weather API and represent it as
|
|||||||
|
|
||||||
### Key References
|
### Key References
|
||||||
|
|
||||||
- `docs/integrations/weatherapi.md` describes the weatherapi public API
|
- `docs/integrations/weatherapi.md` describes the weatherapi public API.
|
||||||
- The local API endpoint is available at `https://weather.api.rakestrawhome.com/` and will return live data
|
- The local API endpoint is available at `https://weather.api.rakestrawhome.com/` and will return live data.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
@@ -130,30 +156,57 @@ Fetch normalized weather data from the internal weather API and represent it as
|
|||||||
|
|
||||||
1. Define the internal `forecast.Bundle` type.
|
1. Define the internal `forecast.Bundle` type.
|
||||||
2. Define source substructures for:
|
2. Define source substructures for:
|
||||||
|
- Latest observation.
|
||||||
|
- Current conditions.
|
||||||
- Hourly forecast data.
|
- Hourly forecast data.
|
||||||
- Daily forecast data (NOTE: not yet implemented upstream in weatherapi, so this can remain a stub in the initial implementation).
|
|
||||||
- NWS narrative forecast periods.
|
- NWS narrative forecast periods.
|
||||||
- NWS alerts.
|
- NWS alerts.
|
||||||
- NWS forecast discussion.
|
- NWS forecast discussion.
|
||||||
- NWS weather story (NOTE: not yet implemented upstream in weatherapi, so this can remain a stub in the initial implementation).
|
- Daily forecast data as a stub source slot until upstream support exists.
|
||||||
3. Implement the weather API client.
|
- NWS weather story as a stub source slot until upstream support exists.
|
||||||
4. Add context-aware HTTP calls and timeouts.
|
3. Implement the weather API client as a fan-out adapter that assembles one bundle from multiple endpoints.
|
||||||
5. Add actionable errors for failed API calls and decode failures.
|
4. Fetch full `/forecast/hourly` and `/forecast/narrative` products, not day-slice endpoints, so Go domain code owns report-period selection.
|
||||||
6. Add fixture support for tests.
|
5. Apply configured query defaults to requests:
|
||||||
7. Optionally add a debug command or app method to fetch and save the raw normalized bundle.
|
- `format=json`
|
||||||
|
- `units=us`, unless overridden
|
||||||
|
- `tz=Chicago`, unless overridden on endpoints that support timezone
|
||||||
|
6. Add context-aware HTTP calls and timeouts.
|
||||||
|
7. Add source provenance to the bundle:
|
||||||
|
- endpoint
|
||||||
|
- query
|
||||||
|
- fetched time
|
||||||
|
- issued/updated time when available
|
||||||
|
- SHA-256 over canonical/minified raw `data` JSON
|
||||||
|
- warnings
|
||||||
|
8. Represent source warnings as first-class records with source name, code, severity, message, endpoint, and completeness impact.
|
||||||
|
9. Require hourly forecast data for normal scheduled reports.
|
||||||
|
10. Apply configured missing-source policy to missing observations, current conditions, alerts, discussion, daily forecast stub, weather story stub, and malformed non-required source sections:
|
||||||
|
- `error`: fail the bundle fetch
|
||||||
|
- `warn`: include a source warning and continue
|
||||||
|
- `none`: omit the warning and continue
|
||||||
|
11. Add actionable errors for failed API calls and decode failures.
|
||||||
|
12. Add fixture support for tests.
|
||||||
|
13. Add a debug command or app method to fetch and save the raw normalized bundle for fixture capture and inspection.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- Weather API adapter can fetch a bundle for a configured location.
|
- Weather API adapter can fetch and assemble a bundle from the configured endpoint.
|
||||||
- Forecast bundle type is available to downstream packages.
|
- Forecast bundle type is available to downstream packages.
|
||||||
|
- Bundle source provenance and warnings are inspectable.
|
||||||
- Tests can use fixtures without real API calls.
|
- Tests can use fixtures without real API calls.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Decode representative API fixture into `forecast.Bundle`.
|
- Decode representative API fixtures into `forecast.Bundle`.
|
||||||
|
- Fan-out success across source endpoints.
|
||||||
- HTTP error handling.
|
- HTTP error handling.
|
||||||
- Timeout/cancellation behavior.
|
- Timeout/cancellation behavior.
|
||||||
|
- `data:null` behavior under `error`, `warn`, and `none`.
|
||||||
- Missing or malformed source sections.
|
- Missing or malformed source sections.
|
||||||
|
- Query construction for `units=us` and `tz=Chicago`.
|
||||||
|
- Full-product forecast endpoint selection.
|
||||||
|
- Required hourly forecast behavior.
|
||||||
|
- SHA-256 source identity behavior.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
@@ -211,7 +264,7 @@ Implement deterministic forecast processing needed by the Daily Report.
|
|||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
|
|
||||||
Centralize report definitions and valid-period behavior before building report-specific briefings.
|
Centralize report definitions, compatible comparison strategies, and valid-period behavior before building report-specific briefings.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
@@ -230,19 +283,24 @@ Centralize report definitions and valid-period behavior before building report-s
|
|||||||
2. Define report metadata structures.
|
2. Define report metadata structures.
|
||||||
3. Define a report `Definition` contract.
|
3. Define a report `Definition` contract.
|
||||||
4. Implement a registry.
|
4. Implement a registry.
|
||||||
5. Implement valid-period resolvers:
|
5. Implement valid-period resolvers using the configured local timezone, default `Chicago`, and half-open `[start,end)` intervals:
|
||||||
- Today Daily Report.
|
- Today Daily Report: current local civil day, `[00:00, next 00:00)`.
|
||||||
- Tomorrow Planning Brief.
|
- Tomorrow Planning Brief: next local civil day.
|
||||||
- 3-Day Outlook.
|
- 3-Day Outlook: generation time through local midnight after the second following local civil day.
|
||||||
- Weekend Outlook.
|
- Weekend Outlook: Monday through Thursday covers Saturday 00:00 to Monday 00:00; Friday and Saturday cover `max(generation time, Friday 18:00)` to Monday 00:00; scheduled Sunday morning skips Weekend Outlook.
|
||||||
- Storm Report placeholder.
|
- Storm Report: explicit `--start` and `--end`.
|
||||||
6. Define default prompt IDs:
|
6. Parse manual storm period bounds from `YYYY-MM-DDTHH:MM` in the configured timezone or RFC3339 timestamps with explicit offsets.
|
||||||
|
7. Define default prompt IDs:
|
||||||
- `weather.daily_report`
|
- `weather.daily_report`
|
||||||
- `weather.tomorrow_report`, or reuse `weather.daily_report` if preferred.
|
- `weather.daily_report` for `daily_tomorrow`; this prompt covers one civil day.
|
||||||
- `weather.three_day_outlook`
|
- `weather.three_day_outlook`
|
||||||
- `weather.weekend_outlook`
|
- `weather.weekend_outlook`
|
||||||
- `weather.storm_report`
|
- `weather.storm_report`
|
||||||
7. Implement batch membership rules:
|
8. Define Recent Changes matching strategies in report definitions:
|
||||||
|
- Daily Today, Daily Tomorrow, and compatible date slices from multi-day reports may compare by same valid local date when marked compatible.
|
||||||
|
- Weekend compares by same weekend window.
|
||||||
|
- Storm compares by explicit event window.
|
||||||
|
9. Implement batch membership rules:
|
||||||
- Morning batch: Daily Today, 3-Day Outlook, Weekend Outlook except Sunday.
|
- Morning batch: Daily Today, 3-Day Outlook, Weekend Outlook except Sunday.
|
||||||
- Evening batch: Daily Tomorrow.
|
- Evening batch: Daily Tomorrow.
|
||||||
|
|
||||||
@@ -250,20 +308,21 @@ Centralize report definitions and valid-period behavior before building report-s
|
|||||||
|
|
||||||
- App layer can resolve which reports should run for a command.
|
- App layer can resolve which reports should run for a command.
|
||||||
- Each report has a valid period independent of generation time.
|
- Each report has a valid period independent of generation time.
|
||||||
- Report definitions map to prompt IDs.
|
- Report definitions map to prompt IDs and comparison strategies.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Daily valid period for different generation times.
|
- Daily valid period for different generation times.
|
||||||
- Tomorrow valid period from evening generation.
|
- Tomorrow valid period from evening generation.
|
||||||
- 3-day period calculation.
|
- 3-Day period calculation from generation time.
|
||||||
- Weekend period calculation on Monday, Friday, Saturday, and Sunday.
|
- Weekend period calculation on Monday, Friday, Saturday, and Sunday.
|
||||||
|
- Storm manual period parsing and validation.
|
||||||
- Morning batch skips Weekend Outlook on Sunday.
|
- Morning batch skips Weekend Outlook on Sunday.
|
||||||
- Registry lookup errors are actionable.
|
- Registry lookup errors are actionable.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- Report identity and period behavior are stable.
|
- Report identity, period behavior, and compatible comparison rules are stable.
|
||||||
- Later stages can add builders without changing CLI semantics.
|
- Later stages can add builders without changing CLI semantics.
|
||||||
|
|
||||||
## Stage 5: Daily Briefing Builder
|
## Stage 5: Daily Briefing Builder
|
||||||
@@ -282,12 +341,15 @@ Build the first complete report-specific briefing package without invoking the L
|
|||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Define common briefing metadata:
|
1. Define common briefing metadata:
|
||||||
|
- Schema version.
|
||||||
|
- RunID.
|
||||||
- Report type.
|
- Report type.
|
||||||
- Variant.
|
- Variant.
|
||||||
- Location.
|
|
||||||
- Generation time.
|
- Generation time.
|
||||||
|
- Configured units and timezone.
|
||||||
- Valid start/end.
|
- Valid start/end.
|
||||||
- Source timestamps or hashes.
|
- Source location ID/name when provided by upstream.
|
||||||
|
- Source timestamps, SHA-256 hashes, and source warnings.
|
||||||
2. Define the Daily Report briefing schema.
|
2. Define the Daily Report briefing schema.
|
||||||
3. Build Daily Report briefing content:
|
3. Build Daily Report briefing content:
|
||||||
- Bottom-line inputs.
|
- Bottom-line inputs.
|
||||||
@@ -296,7 +358,7 @@ Build the first complete report-specific briefing package without invoking the L
|
|||||||
- Best/worst outdoor window inputs, if derivable.
|
- Best/worst outdoor window inputs, if derivable.
|
||||||
- NWS narrative periods relevant to the day.
|
- NWS narrative periods relevant to the day.
|
||||||
- Forecast discussion summary or selected text from the API data.
|
- Forecast discussion summary or selected text from the API data.
|
||||||
- Weather story summary or selected text from the API data.
|
- Weather story summary or selected text when upstream support exists.
|
||||||
4. Add JSON output for the briefing package.
|
4. Add JSON output for the briefing package.
|
||||||
5. Add an app workflow that can generate the Daily briefing and write it to disk for inspection.
|
5. Add an app workflow that can generate the Daily briefing and write it to disk for inspection.
|
||||||
|
|
||||||
@@ -310,6 +372,8 @@ Build the first complete report-specific briefing package without invoking the L
|
|||||||
- Daily briefing from representative fixture.
|
- Daily briefing from representative fixture.
|
||||||
- Alerts included/excluded correctly.
|
- Alerts included/excluded correctly.
|
||||||
- Source context selection.
|
- Source context selection.
|
||||||
|
- Source warnings included correctly.
|
||||||
|
- RunID included correctly.
|
||||||
- Empty or quiet-weather behavior.
|
- Empty or quiet-weather behavior.
|
||||||
- Snapshot metadata completeness.
|
- Snapshot metadata completeness.
|
||||||
|
|
||||||
@@ -318,97 +382,69 @@ Build the first complete report-specific briefing package without invoking the L
|
|||||||
- The Daily briefing package is useful as prompt input.
|
- The Daily briefing package is useful as prompt input.
|
||||||
- The app can produce the briefing artifact from real or fixture data.
|
- The app can produce the briefing artifact from real or fixture data.
|
||||||
|
|
||||||
## Stage 6: Prompt Variable Builder
|
## Stage 6: Prompt Input Package and Scriptorium Render Preflight
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
|
|
||||||
Convert a briefing package into the structured variable payload expected by `scriptorium` prompts.
|
Convert a briefing package into the structured `data_package` input expected by `scriptorium` prompts and validate prompt wiring without LLM generation.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
|
||||||
|
|
||||||
- `internal/promptvars`
|
|
||||||
- `internal/briefing`
|
|
||||||
- `internal/report`
|
|
||||||
- `internal/app`
|
|
||||||
|
|
||||||
### Work Items
|
|
||||||
|
|
||||||
1. Define prompt variable schema structures.
|
|
||||||
2. Build variables from report metadata and briefing content.
|
|
||||||
3. Include placeholders for Recent Changes, initially empty.
|
|
||||||
4. Validate required fields before rendering.
|
|
||||||
5. Write vars JSON to the workspace.
|
|
||||||
6. Ensure vars output is stable and inspectable.
|
|
||||||
|
|
||||||
### Deliverables
|
|
||||||
|
|
||||||
- Daily Report prompt vars can be generated and written to a file.
|
|
||||||
- The vars file is suitable for `scriptorium run --vars-file`.
|
|
||||||
|
|
||||||
### Tests
|
|
||||||
|
|
||||||
- Prompt vars generated from Daily briefing fixture.
|
|
||||||
- Missing required fields fail validation.
|
|
||||||
- JSON output is deterministic where practical.
|
|
||||||
|
|
||||||
### Done Criteria
|
|
||||||
|
|
||||||
- The app can prepare a complete vars file for a Daily Report.
|
|
||||||
- LLM rendering is the only missing step for the first end-to-end report.
|
|
||||||
|
|
||||||
## Stage 7: Scriptorium Adapter and First End-to-End Daily Report
|
|
||||||
|
|
||||||
### Goal
|
|
||||||
|
|
||||||
Invoke `scriptorium` as a subprocess and produce the first rendered Markdown report.
|
|
||||||
|
|
||||||
### Key References
|
### Key References
|
||||||
- `docs/integrations/scriptorium.md` describes the CLI contract for running `scriptorium` as a subprocess.
|
|
||||||
|
- `docs/integrations/scriptorium.md` describes the CLI contract for `scriptorium render`.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
|
- `internal/promptinput`
|
||||||
|
- `internal/briefing`
|
||||||
|
- `internal/report`
|
||||||
- `internal/adapters/scriptorium`
|
- `internal/adapters/scriptorium`
|
||||||
- `internal/app`
|
- `internal/app`
|
||||||
- `internal/state`, minimally if needed for output paths
|
|
||||||
|
|
||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Define `scriptorium.Runner` interface and request/result types.
|
1. Define prompt input data package schema structures.
|
||||||
2. Implement subprocess execution with `exec.CommandContext`.
|
2. Build `data_package` JSON from report metadata, briefing content, source warnings, RunID, and an initially empty Recent Changes section.
|
||||||
3. Pass arguments without shell interpolation.
|
3. Validate required data package fields before rendering.
|
||||||
4. Prefer `--vars-file` for prompt variables.
|
4. Write data package JSON to the workspace.
|
||||||
5. Capture stderr and stdout with reasonable limits.
|
5. Implement `scriptorium render` support in the adapter.
|
||||||
6. Apply timeout and cancellation.
|
6. Invoke preflight as:
|
||||||
7. Return actionable errors for nonzero exits.
|
|
||||||
8. Wire Daily Report generation end-to-end:
|
```text
|
||||||
- Fetch bundle.
|
scriptorium render \
|
||||||
- Build briefing.
|
--prompt <prompt_id> \
|
||||||
- Build vars.
|
--input data_package=<path> \
|
||||||
- Run `scriptorium`.
|
--format json
|
||||||
- Write Markdown report.
|
```
|
||||||
|
|
||||||
|
7. Capture stdout and stderr separately.
|
||||||
|
8. Persist render/preflight output for inspection.
|
||||||
|
9. Treat render preflight as always-on before `scriptorium run` for MVP generated reports.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- `weatherreporter generate daily --location home --out ./daily.md` produces a Markdown report.
|
- Daily Report data package can be generated and written to a file.
|
||||||
- Failures include useful context.
|
- The data package is suitable for `scriptorium render --input data_package=<path>`.
|
||||||
|
- Prompt/input wiring can be checked without LLM execution.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Adapter command construction using a fake command runner or fake executable.
|
- Data package generated from Daily briefing fixture.
|
||||||
- Nonzero exit handling.
|
- Missing required fields fail validation.
|
||||||
- Timeout behavior.
|
- JSON output is deterministic where practical.
|
||||||
- App workflow test using fake weather client and fake `scriptorium` runner.
|
- Adapter command construction for `scriptorium render`.
|
||||||
|
- Nonzero render exit handling.
|
||||||
|
- Always-on preflight behavior in the generation workflow.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- The first report can be generated end-to-end.
|
- The app can prepare and preflight a complete data package for a Daily Report.
|
||||||
- `scriptorium` is isolated behind the adapter package.
|
- LLM rendering is the only missing step for the first end-to-end report.
|
||||||
|
|
||||||
## Stage 8: Filesystem State Store and Metadata Persistence
|
## Stage 7: Filesystem State Store and Metadata Baseline
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
|
|
||||||
Persist report artifacts and metadata in a durable, inspectable structure.
|
Persist report artifacts and metadata in a durable, inspectable structure before the first LLM-generated report.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
@@ -420,15 +456,19 @@ Persist report artifacts and metadata in a durable, inspectable structure.
|
|||||||
1. Define state store interface.
|
1. Define state store interface.
|
||||||
2. Implement filesystem-backed store.
|
2. Implement filesystem-backed store.
|
||||||
3. Persist briefing snapshots.
|
3. Persist briefing snapshots.
|
||||||
4. Persist prompt variable files.
|
4. Persist prompt input data package files.
|
||||||
5. Persist report metadata.
|
5. Persist `scriptorium render` preflight output.
|
||||||
6. Persist rendered Markdown reports when output path is managed by the app.
|
6. Persist report metadata.
|
||||||
7. Use atomic writes where practical.
|
7. Add RunID as an explicit metadata concept based on generation timestamp plus report ID.
|
||||||
8. Implement lookup for prior comparable snapshots.
|
8. Name managed report files with the generation timestamp to avoid overwriting previous runs for the same valid period.
|
||||||
|
9. Link valid period, RunID, briefing snapshot, data package, preflight output, rendered report, source warnings, and source hashes in metadata.
|
||||||
|
10. Use atomic writes where practical.
|
||||||
|
11. Implement lookup for prior comparable Daily snapshots.
|
||||||
|
12. Keep paths narrow and predictable.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- Each generated report has associated metadata and briefing snapshot.
|
- Each Daily preflight run has associated metadata, RunID, briefing snapshot, data package, and render output.
|
||||||
- Prior comparable snapshot lookup works for Daily Reports.
|
- Prior comparable snapshot lookup works for Daily Reports.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
@@ -436,25 +476,92 @@ Persist report artifacts and metadata in a durable, inspectable structure.
|
|||||||
- Atomic write behavior where feasible.
|
- Atomic write behavior where feasible.
|
||||||
- Metadata round-trip.
|
- Metadata round-trip.
|
||||||
- Snapshot path generation.
|
- Snapshot path generation.
|
||||||
|
- Data package path generation.
|
||||||
|
- Preflight output path generation.
|
||||||
|
- Timestamped managed report path generation.
|
||||||
|
- RunID metadata behavior.
|
||||||
- Prior snapshot lookup.
|
- Prior snapshot lookup.
|
||||||
- Narrow-path safety behavior.
|
- Narrow-path safety behavior.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- Daily reports leave enough state for inspection and future Recent Changes.
|
- Daily report preparation leaves enough state for inspection and future Recent Changes.
|
||||||
- State layout is predictable and documented.
|
- State layout is predictable and documented.
|
||||||
|
|
||||||
|
## Stage 8: Scriptorium Run Adapter and First End-to-End Daily Report
|
||||||
|
|
||||||
|
### Goal
|
||||||
|
|
||||||
|
Invoke `scriptorium run` as a subprocess and produce the first rendered Markdown report.
|
||||||
|
|
||||||
|
### Key References
|
||||||
|
|
||||||
|
- `docs/integrations/scriptorium.md` describes the CLI contract for running `scriptorium` as a subprocess.
|
||||||
|
|
||||||
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
|
- `internal/adapters/scriptorium`
|
||||||
|
- `internal/app`
|
||||||
|
- `internal/state`
|
||||||
|
|
||||||
|
### Work Items
|
||||||
|
|
||||||
|
1. Define `scriptorium.Run` request/result types or extend the runner interface introduced for render preflight.
|
||||||
|
2. Implement subprocess execution with `exec.CommandContext`.
|
||||||
|
3. Pass arguments without shell interpolation.
|
||||||
|
4. Pass the prompt input data package with `--input data_package=<path>`.
|
||||||
|
5. Invoke generation as:
|
||||||
|
|
||||||
|
```text
|
||||||
|
scriptorium run \
|
||||||
|
--prompt <prompt_id> \
|
||||||
|
--input data_package=<path> \
|
||||||
|
--out <artifact_path>
|
||||||
|
```
|
||||||
|
|
||||||
|
6. Capture stderr and stdout with reasonable limits.
|
||||||
|
7. Apply timeout and cancellation.
|
||||||
|
8. Return actionable errors for nonzero exits, including exit code `2`, which can still produce output.
|
||||||
|
9. Wire Daily Report generation end-to-end:
|
||||||
|
- Fetch bundle.
|
||||||
|
- Build briefing.
|
||||||
|
- Build data package.
|
||||||
|
- Run render preflight.
|
||||||
|
- Run `scriptorium`.
|
||||||
|
- Write Markdown report.
|
||||||
|
- Persist metadata and snapshots.
|
||||||
|
|
||||||
|
### Deliverables
|
||||||
|
|
||||||
|
- `weatherreporter generate daily --out ./daily.md` produces a Markdown report.
|
||||||
|
- Failures include useful context.
|
||||||
|
- The first end-to-end report already has durable briefing, data package, metadata, and source provenance.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
- Adapter command construction using a fake command runner or fake executable.
|
||||||
|
- Nonzero exit handling.
|
||||||
|
- Exit code `2` handling.
|
||||||
|
- Timeout behavior.
|
||||||
|
- Always-on preflight before run.
|
||||||
|
- App workflow test using fake weather client and fake `scriptorium` runner.
|
||||||
|
|
||||||
|
### Done Criteria
|
||||||
|
|
||||||
|
- The first report can be generated end-to-end.
|
||||||
|
- `scriptorium` is isolated behind the adapter package.
|
||||||
|
|
||||||
## Stage 9: Recent Changes for Daily Reports
|
## Stage 9: Recent Changes for Daily Reports
|
||||||
|
|
||||||
### Goal
|
### Goal
|
||||||
|
|
||||||
Add structured comparison of Daily Report briefing snapshots and include meaningful changes in prompt variables.
|
Add structured comparison of Daily Report briefing snapshots and include meaningful changes in prompt input data packages.
|
||||||
|
|
||||||
### Packages Introduced or Expanded
|
### Packages Introduced or Expanded
|
||||||
|
|
||||||
- `internal/changes`
|
- `internal/changes`
|
||||||
- `internal/state`
|
- `internal/state`
|
||||||
- `internal/promptvars`
|
- `internal/promptinput`
|
||||||
- `internal/app`
|
- `internal/app`
|
||||||
|
|
||||||
### Work Items
|
### Work Items
|
||||||
@@ -470,12 +577,12 @@ Add structured comparison of Daily Report briefing snapshots and include meaning
|
|||||||
- Alert changes.
|
- Alert changes.
|
||||||
- Wind gust changes.
|
- Wind gust changes.
|
||||||
- Snow/ice/thunder risk changes.
|
- Snow/ice/thunder risk changes.
|
||||||
6. Add Recent Changes to prompt vars.
|
6. Add Recent Changes to the data package.
|
||||||
7. Omit or minimize Recent Changes when no meaningful changes exist.
|
7. Omit or minimize Recent Changes when no meaningful changes exist.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- Daily Report vars include Recent Changes when appropriate.
|
- Daily Report data packages include Recent Changes when appropriate.
|
||||||
- Daily Report generation persists current snapshot after comparison.
|
- Daily Report generation persists current snapshot after comparison.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
@@ -485,11 +592,11 @@ Add structured comparison of Daily Report briefing snapshots and include meaning
|
|||||||
- Temperature threshold crossing.
|
- Temperature threshold crossing.
|
||||||
- Precipitation timing shift.
|
- Precipitation timing shift.
|
||||||
- Alert added/removed behavior.
|
- Alert added/removed behavior.
|
||||||
- Comparison uses valid period, not just generation time.
|
- Comparison uses valid period and compatible strategy, not just generation time.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- The Daily Report can say what changed relative to the prior report covering the same forecast period.
|
- The Daily Report can say what changed relative to a prior compatible report covering the same forecast period.
|
||||||
- Markdown report text is not used as the comparison source.
|
- Markdown report text is not used as the comparison source.
|
||||||
|
|
||||||
## Stage 10: Tomorrow Planning Brief
|
## Stage 10: Tomorrow Planning Brief
|
||||||
@@ -508,24 +615,24 @@ Add the evening Tomorrow Planning Brief using the Daily Report machinery where p
|
|||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Implement the `daily_tomorrow` report definition fully.
|
1. Implement the `daily_tomorrow` report definition fully.
|
||||||
2. Reuse or specialize the Daily briefing builder for tomorrow’s valid date.
|
2. Reuse or specialize the Daily briefing builder for tomorrow's valid date.
|
||||||
3. Add any tomorrow-specific planning fields, such as:
|
3. Add any tomorrow-specific planning fields, such as:
|
||||||
- Morning readiness note inputs.
|
- Morning readiness note inputs.
|
||||||
- Commute/school/workday concerns.
|
- Commute/school/workday concerns.
|
||||||
- What may change overnight.
|
- What may change overnight.
|
||||||
4. Ensure comparison can find a prior report covering the same valid day where appropriate.
|
4. Ensure comparison can find a prior compatible report covering the same valid local date.
|
||||||
5. Implement `run evening` as Daily Tomorrow.
|
5. Implement `run evening` as Daily Tomorrow.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- `weatherreporter generate tomorrow --location home` works end-to-end.
|
- `weatherreporter generate tomorrow` works end-to-end.
|
||||||
- `weatherreporter run evening --location home` works.
|
- `weatherreporter run evening` works.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Tomorrow valid-period calculation.
|
- Tomorrow valid-period calculation.
|
||||||
- Tomorrow briefing uses the correct date.
|
- Tomorrow briefing uses the correct date.
|
||||||
- Recent Changes can compare against prior 3-Day or prior Tomorrow snapshot if configured.
|
- Recent Changes can compare against a compatible prior Tomorrow, Daily, or 3-Day snapshot when configured by the registry.
|
||||||
- Evening batch includes only the expected report.
|
- Evening batch includes only the expected report.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
@@ -551,32 +658,32 @@ Add the 3-Day Outlook report using the same architecture.
|
|||||||
|
|
||||||
1. Implement 3-Day valid-period resolution.
|
1. Implement 3-Day valid-period resolution.
|
||||||
2. Build a 3-Day briefing package.
|
2. Build a 3-Day briefing package.
|
||||||
3. Summarize each day:
|
3. Summarize each day or partial day:
|
||||||
- Overall character.
|
- Overall character.
|
||||||
- Temperature range.
|
- Temperature range.
|
||||||
- Precipitation/storm/winter/heat/wind risks.
|
- Precipitation/storm/winter/heat/wind risks.
|
||||||
- Best/worst windows if derivable.
|
- Best/worst windows if derivable.
|
||||||
- Relevant alerts.
|
- Relevant alerts.
|
||||||
4. Attach broader NWS context, especially forecast discussion and weather story inputs.
|
4. Attach broader NWS context, especially forecast discussion and weather story inputs when available.
|
||||||
5. Implement 3-Day Recent Changes strategy.
|
5. Implement 3-Day Recent Changes strategy.
|
||||||
6. Add end-to-end generation.
|
6. Add end-to-end generation.
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- `weatherreporter generate three-day --location home` produces Markdown.
|
- `weatherreporter generate three-day` produces Markdown.
|
||||||
- Morning batch can include the 3-Day Outlook.
|
- Morning batch can include the 3-Day Outlook.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Three-day valid period.
|
- Three-day valid period from generation time.
|
||||||
- Daily aggregation across three days.
|
- Daily aggregation across the 3-Day window.
|
||||||
- Alert overlap across multi-day period.
|
- Alert overlap across multi-day period.
|
||||||
- Recent Changes across multi-day snapshots.
|
- Recent Changes across multi-day snapshots.
|
||||||
- Quiet-weather behavior.
|
- Quiet-weather behavior.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
- The 3-Day Outlook is generated using the same registry, briefing, vars, state, and rendering pipeline as the Daily Report.
|
- The 3-Day Outlook is generated using the same registry, briefing, data package, state, and rendering pipeline as the Daily Report.
|
||||||
|
|
||||||
## Stage 12: Weekend Outlook
|
## Stage 12: Weekend Outlook
|
||||||
|
|
||||||
@@ -595,9 +702,9 @@ Add the Weekend Outlook with day-of-week-sensitive period behavior.
|
|||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Implement Weekend valid-period resolution:
|
1. Implement Weekend valid-period resolution:
|
||||||
- Monday through Thursday: upcoming Saturday/Sunday, optionally Friday evening if configured.
|
- Monday through Thursday: upcoming Saturday 00:00 through Monday 00:00.
|
||||||
- Friday: Friday evening through Sunday night.
|
- Friday: `max(generation time, Friday 18:00)` through Monday 00:00.
|
||||||
- Saturday: remaining weekend.
|
- Saturday: generation time through Monday 00:00.
|
||||||
- Sunday: normally not generated by the scheduled morning batch.
|
- Sunday: normally not generated by the scheduled morning batch.
|
||||||
2. Build Weekend briefing package.
|
2. Build Weekend briefing package.
|
||||||
3. Emphasize planning fields:
|
3. Emphasize planning fields:
|
||||||
@@ -611,8 +718,8 @@ Add the Weekend Outlook with day-of-week-sensitive period behavior.
|
|||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- `weatherreporter generate weekend --location home` produces Markdown.
|
- `weatherreporter generate weekend` produces Markdown.
|
||||||
- `weatherreporter run morning --location home` includes Weekend Outlook except Sunday.
|
- `weatherreporter run morning` includes Weekend Outlook except Sunday.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
@@ -643,27 +750,27 @@ Make scheduled workflows reliable enough for unattended execution by cron, syste
|
|||||||
|
|
||||||
1. Finalize `run morning` workflow.
|
1. Finalize `run morning` workflow.
|
||||||
2. Finalize `run evening` workflow.
|
2. Finalize `run evening` workflow.
|
||||||
3. Decide failure behavior:
|
3. Continue remaining independent reports after one report fails.
|
||||||
- Continue remaining reports after one report fails, or fail fast.
|
4. Return nonzero from the CLI if any report failed.
|
||||||
- Return aggregate status.
|
5. Add structured aggregate run summaries.
|
||||||
4. Add structured run summaries.
|
6. Ensure each report run records enough metadata for troubleshooting.
|
||||||
5. Ensure each report run records enough metadata for troubleshooting.
|
7. Add CLI flags for output directory and optional dry-run/data-package-only mode if desired.
|
||||||
6. Add CLI flags for output directory, location, and optional dry-run/vars-only mode if desired.
|
8. Add logging suitable for scheduled execution.
|
||||||
7. Add logging suitable for scheduled execution.
|
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- Morning batch can generate Daily, 3-Day, and Weekend reports.
|
- Morning batch can generate Daily, 3-Day, and Weekend reports.
|
||||||
- Evening batch can generate Tomorrow Planning Brief.
|
- Evening batch can generate Tomorrow Planning Brief.
|
||||||
- Failures are understandable from logs and metadata.
|
- Failures are understandable from logs, metadata, and aggregate summaries.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Morning batch report selection.
|
- Morning batch report selection.
|
||||||
- Evening batch report selection.
|
- Evening batch report selection.
|
||||||
- Partial failure behavior.
|
- Partial failure continues independent reports.
|
||||||
|
- Aggregate nonzero exit behavior.
|
||||||
- Output path behavior.
|
- Output path behavior.
|
||||||
- Dry-run or vars-only behavior, if implemented.
|
- Dry-run or data-package-only behavior, if implemented.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
@@ -686,11 +793,11 @@ Add manual Storm Report generation without building the automatic monitoring age
|
|||||||
### Work Items
|
### Work Items
|
||||||
|
|
||||||
1. Implement Storm Report definition.
|
1. Implement Storm Report definition.
|
||||||
2. Define storm valid-period behavior.
|
2. Require explicit storm valid-period bounds via `--start` and `--end`.
|
||||||
3. Build storm briefing package from:
|
3. Build storm briefing package from:
|
||||||
- Active alerts.
|
- Active alerts.
|
||||||
- Forecast discussion.
|
- Forecast discussion.
|
||||||
- Weather story.
|
- Weather story when available.
|
||||||
- Relevant hourly/daily periods.
|
- Relevant hourly/daily periods.
|
||||||
- NWS narrative periods.
|
- NWS narrative periods.
|
||||||
4. Include storm-specific fields:
|
4. Include storm-specific fields:
|
||||||
@@ -702,7 +809,7 @@ Add manual Storm Report generation without building the automatic monitoring age
|
|||||||
- Confidence and uncertainty inputs.
|
- Confidence and uncertainty inputs.
|
||||||
- What to watch next.
|
- What to watch next.
|
||||||
5. Add manual command:
|
5. Add manual command:
|
||||||
- `weatherreporter generate storm --location home`
|
- `weatherreporter generate storm --start <time> --end <time>`
|
||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
@@ -714,6 +821,7 @@ Add manual Storm Report generation without building the automatic monitoring age
|
|||||||
- Storm briefing with active alerts.
|
- Storm briefing with active alerts.
|
||||||
- Storm briefing with forecast discussion but no active alert.
|
- Storm briefing with forecast discussion but no active alert.
|
||||||
- Quiet/no-storm behavior.
|
- Quiet/no-storm behavior.
|
||||||
|
- Manual period parsing and validation.
|
||||||
- Relevant source selection.
|
- Relevant source selection.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
@@ -740,7 +848,8 @@ Make generated artifacts easy to inspect and debug.
|
|||||||
- Show metadata for a report.
|
- Show metadata for a report.
|
||||||
- Show prior comparable snapshot chosen for Recent Changes.
|
- Show prior comparable snapshot chosen for Recent Changes.
|
||||||
- Emit briefing JSON without rendering.
|
- Emit briefing JSON without rendering.
|
||||||
- Emit prompt vars without rendering.
|
- Emit data package JSON without rendering.
|
||||||
|
- Show source warnings and provenance.
|
||||||
2. Add clear paths to generated artifacts in command output.
|
2. Add clear paths to generated artifacts in command output.
|
||||||
3. Ensure logs do not dump large weather payloads by default.
|
3. Ensure logs do not dump large weather payloads by default.
|
||||||
|
|
||||||
@@ -748,12 +857,14 @@ Make generated artifacts easy to inspect and debug.
|
|||||||
|
|
||||||
- Developers can inspect why a report was generated a certain way.
|
- Developers can inspect why a report was generated a certain way.
|
||||||
- Recent Changes comparison inputs are discoverable.
|
- Recent Changes comparison inputs are discoverable.
|
||||||
|
- Source warnings are discoverable.
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
- Inspection command behavior with fixture state.
|
- Inspection command behavior with fixture state.
|
||||||
- Missing artifact errors.
|
- Missing artifact errors.
|
||||||
- Metadata lookup behavior.
|
- Metadata lookup behavior.
|
||||||
|
- Source warning display behavior.
|
||||||
|
|
||||||
### Done Criteria
|
### Done Criteria
|
||||||
|
|
||||||
@@ -781,7 +892,7 @@ Potentially:
|
|||||||
3. Use source signals such as:
|
3. Use source signals such as:
|
||||||
- Active alerts.
|
- Active alerts.
|
||||||
- Forecast discussion hazard wording.
|
- Forecast discussion hazard wording.
|
||||||
- Weather Story emphasis.
|
- Weather Story emphasis when available.
|
||||||
- Hourly/daily threshold crossings.
|
- Hourly/daily threshold crossings.
|
||||||
- Material forecast changes toward higher impact.
|
- Material forecast changes toward higher impact.
|
||||||
4. Add an LLM event evaluator through `scriptorium` or a future native LLM adapter.
|
4. Add an LLM event evaluator through `scriptorium` or a future native LLM adapter.
|
||||||
@@ -797,7 +908,7 @@ Potentially:
|
|||||||
|
|
||||||
### Deliverables
|
### Deliverables
|
||||||
|
|
||||||
- `weatherreporter evaluate storm --location home` can decide whether a Storm Report is warranted.
|
- `weatherreporter evaluate storm` can decide whether a Storm Report is warranted.
|
||||||
- Event lifecycle state is persisted.
|
- Event lifecycle state is persisted.
|
||||||
- Storm Report updates are generated only for meaningful changes.
|
- Storm Report updates are generated only for meaningful changes.
|
||||||
|
|
||||||
@@ -819,28 +930,29 @@ Potentially:
|
|||||||
The first meaningful milestone should be:
|
The first meaningful milestone should be:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
weatherreporter generate daily --location home --out ./daily.md
|
weatherreporter generate daily --out ./daily.md
|
||||||
```
|
```
|
||||||
|
|
||||||
This command should:
|
This command should:
|
||||||
|
|
||||||
1. Load config.
|
1. Load config.
|
||||||
2. Fetch weather data.
|
2. Fetch weather data from the configured endpoint.
|
||||||
3. Build a Daily briefing package.
|
3. Build a Daily briefing package.
|
||||||
4. Build prompt variables.
|
4. Build a prompt input data package.
|
||||||
5. Invoke `scriptorium`.
|
5. Run `scriptorium render` preflight.
|
||||||
6. Write Markdown output.
|
6. Invoke `scriptorium run`.
|
||||||
7. Persist metadata and snapshots.
|
7. Write Markdown output.
|
||||||
|
8. Persist metadata, source provenance, source warnings, the briefing snapshot, and the data package.
|
||||||
|
|
||||||
Do not implement all report types before this milestone. One complete vertical slice will reveal schema, state, prompt-variable, and adapter issues earlier than a broad but shallow implementation.
|
Do not implement all report types before this milestone. One complete vertical slice will reveal schema, state, prompt input, and adapter issues earlier than a broad but shallow implementation.
|
||||||
|
|
||||||
## Suggested Second Implementation Milestone
|
## Suggested Second Implementation Milestone
|
||||||
|
|
||||||
The second milestone should be:
|
The second milestone should be:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
weatherreporter run morning --location home
|
weatherreporter run morning
|
||||||
weatherreporter run evening --location home
|
weatherreporter run evening
|
||||||
```
|
```
|
||||||
|
|
||||||
At this point, the app should support:
|
At this point, the app should support:
|
||||||
@@ -852,13 +964,14 @@ At this point, the app should support:
|
|||||||
- Recent Changes for all scheduled report types.
|
- Recent Changes for all scheduled report types.
|
||||||
- Filesystem state and metadata.
|
- Filesystem state and metadata.
|
||||||
- Reliable scheduled execution.
|
- Reliable scheduled execution.
|
||||||
|
- Partial-failure continuation with nonzero aggregate exit status.
|
||||||
|
|
||||||
## Suggested Third Implementation Milestone
|
## Suggested Third Implementation Milestone
|
||||||
|
|
||||||
The third milestone should be:
|
The third milestone should be:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
weatherreporter generate storm --location home
|
weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00
|
||||||
```
|
```
|
||||||
|
|
||||||
At this point, Storm Reports can be generated manually using the same pipeline. Automatic storm monitoring should remain future work until manual Storm Reports are useful and stable.
|
At this point, Storm Reports can be generated manually using the same pipeline. Automatic storm monitoring should remain future work until manual Storm Reports are useful and stable.
|
||||||
@@ -871,6 +984,7 @@ Do not implement these in the initial prototype unless required by real use:
|
|||||||
- Daemon mode.
|
- Daemon mode.
|
||||||
- Automatic storm-monitoring agent.
|
- Automatic storm-monitoring agent.
|
||||||
- Database-backed state.
|
- Database-backed state.
|
||||||
|
- Multi-location weatherreporter selection.
|
||||||
- Multi-user authorization.
|
- Multi-user authorization.
|
||||||
- Public HTTP API.
|
- Public HTTP API.
|
||||||
- Complex plugin system.
|
- Complex plugin system.
|
||||||
@@ -882,7 +996,7 @@ Do not implement these in the initial prototype unless required by real use:
|
|||||||
The most important early design decision is to make the briefing package the central artifact. Once the briefing package is stable, every report follows the same basic path:
|
The most important early design decision is to make the briefing package the central artifact. Once the briefing package is stable, every report follows the same basic path:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
report definition -> valid period -> forecast selection -> briefing package -> Recent Changes -> prompt vars -> scriptorium -> report metadata
|
report definition -> valid period -> forecast selection -> briefing package -> Recent Changes -> data package -> scriptorium -> report metadata
|
||||||
```
|
```
|
||||||
|
|
||||||
This keeps the application modular, testable, and easy to extend with future report types.
|
This keeps the application modular, testable, and easy to extend with future report types.
|
||||||
|
|||||||
Reference in New Issue
Block a user