32 KiB
Weatherreporter Implementation Roadmap
This roadmap defines a staged implementation plan for weatherreporter, a Go application that prepares human-facing weather reports from normalized weather data collected by weatherfeeder and rendered through scriptorium.
The goal is to build the application in stable layers. Each stage should leave the repository in a working, testable state. Early stages should prioritize inspectable intermediate artifacts over complete automation.
Guiding Implementation Principles
- Build deterministic data preparation before LLM rendering.
- Keep CLI, adapters, domain logic, state, and prompt input construction separate.
- Use fixture-driven tests for forecast processing and briefing builders.
- Persist intermediate artifacts so failed or low-quality reports can be inspected.
- Add one report type fully before generalizing to all report types.
- Treat
scriptoriumas an external adapter during the prototype. - 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.v3for YAML configuration. - Default Weather API query values are
format=json,units=us, andtz=Chicago. - Default missing-source policy is
warn. - Fetch full
/forecast/hourlyand/forecast/narrativeproducts; Go owns report-period selection. - Require hourly forecast data for normal scheduled reports.
- Use
scriptorium renderas an always-on preflight beforescriptorium runfor generated reports. - Pass prompt input to
scriptoriumwith--input data_package=<path>. - Identify source payloads with SHA-256 over canonical/minified raw
dataJSON.
Stage 0: Repository Skeleton and Architecture Baseline
Goal
Create the project skeleton, commit the architecture documents, and establish the package boundaries before adding substantial logic.
Packages Introduced
cmd/weatherreporterinternal/cliinternal/appinternal/config
Work Items
- Initialize the Go module.
- Add the architecture policy document.
- Add the package layout document.
- Add this implementation roadmap.
- Create minimal package directories and placeholder files where useful.
- Add basic build/test tooling.
- Add a minimal
weatherreporter --helpcommand using the Go standard library.
Deliverables
- Go module builds successfully.
go test ./...passes.- Basic CLI entrypoint exists.
- Documentation is present under the appropriate docs directory.
Done Criteria
- The repository has a clear skeleton matching the intended architecture.
- The binary can be built.
- The CLI can display help without loading external services.
Stage 1: Configuration and CLI Foundation
Goal
Implement configuration loading and a stable command shape before integrating external systems.
Packages Introduced or Expanded
internal/configinternal/cliinternal/appinternal/timeutil
Work Items
- Define configuration structs for:
- Weather API base URL, timeout, precision, units, and timezone.
- Missing-source behavior, with a global default and optional per-source overrides.
scriptoriumsettings.- Workspace paths.
- Report output paths.
- Daypart definitions.
- Recent-change thresholds.
- Implement built-in defaults in
internal/config/defaults.go:units=ustz=Chicagoformat=json- missing-source policy
warn
- Implement YAML config loading from:
/usr/local/etc/weatherreporter/config.yml- CLI override via
--config
- Use
gopkg.in/yaml.v3for YAML parsing. - Implement config validation.
- Implement basic command structure with the Go standard library:
generate dailygenerate tomorrowgenerate three-daygenerate weekendgenerate stormrun morningrun evening
- Add CLI flag parsing for:
--config--units--tz--out- optional
--datefor Daily Today, acceptingYYYY-MM-DDand defaulting to the current local date in the configured timezone --startand--endfor manual Storm Reports
- Commands may initially return "not implemented" after config and request resolution.
- Add time-zone and clock helpers.
Deliverables
- Config can be loaded, validated, and inspected in tests.
- CLI commands parse expected flags without a CLI framework dependency.
- App-layer request structs exist for report generation and scheduled batches.
Tests
- Config defaults load successfully, including
units=us,tz=Chicago, and missing-source policywarn. - Example config file load test.
- Invalid config produces actionable errors.
- CLI parser tests for major commands and shared flags.
- Storm
--start/--endparsing tests. - Time-zone resolution tests.
Done Criteria
- CLI request handling is stable enough that later stages can attach real behavior without reshaping commands.
- 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
Goal
Fetch normalized weather data from the internal weather API and represent it as a stable forecast bundle inside the application.
Key References
docs/integrations/weatherapi.mddescribes the weatherapi public API.- The local API endpoint is available at
https://weather.api.rakestrawhome.com/and will return live data.
Packages Introduced or Expanded
internal/adapters/weatherapiinternal/forecastinternal/app
Work Items
- Define the internal
forecast.Bundletype. - Define source substructures for:
- Latest observation.
- Current conditions.
- Hourly forecast data.
- NWS narrative forecast periods.
- NWS alerts.
- NWS forecast discussion.
- Daily forecast data as a stub source slot until upstream support exists.
- NWS weather story as a stub source slot until upstream support exists.
- Implement the weather API client as a fan-out adapter that assembles one bundle from multiple endpoints.
- Fetch full
/forecast/hourlyand/forecast/narrativeproducts, not day-slice endpoints, so Go domain code owns report-period selection. - Apply configured query defaults to requests:
format=jsonunits=us, unless overriddentz=Chicago, unless overridden on endpoints that support timezone
- Add context-aware HTTP calls and timeouts.
- Add source provenance to the bundle:
- endpoint
- query
- fetched time
- issued/updated time when available
- SHA-256 over canonical/minified raw
dataJSON - warnings
- 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 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 fetchwarn: include a source warning and continuenone: omit the warning and continue
- Add actionable errors for failed API calls and decode failures.
- Add fixture support for tests.
- Add a debug command or app method to fetch and save the raw normalized bundle for fixture capture and inspection.
Deliverables
- Weather API adapter can fetch and assemble a bundle from the configured endpoint.
- Forecast bundle type is available to downstream packages.
- Bundle source provenance and warnings are inspectable.
- Tests can use fixtures without real API calls.
Tests
- Decode representative API fixtures into
forecast.Bundle. - Fan-out success across source endpoints.
- HTTP error handling.
- Timeout/cancellation behavior.
data:nullbehavior undererror,warn, andnone.- Missing or malformed source sections.
- Query construction for
units=usandtz=Chicago. - Full-product forecast endpoint selection.
- Required hourly forecast behavior.
- SHA-256 source identity behavior.
Done Criteria
- The app can fetch current weather data and save or log a concise confirmation.
- No report generation is required yet.
Stage 3: Forecast Derivation and Daypart Processing
Goal
Implement deterministic forecast processing needed by the Daily Report.
Packages Introduced or Expanded
internal/forecastinternal/timeutil
Work Items
- Implement configurable daypart definitions.
- Implement daypart overlap logic, including overnight periods.
- Group hourly forecast records into dayparts.
- Compute daypart summaries:
- Temperature range.
- Apparent-temperature range, if available.
- Max precipitation probability and associated hour.
- Peak wind speed.
- Peak wind gust.
- Dominant or notable conditions.
- Thunder, snow, ice, fog, heat, cold, or wind indicators where supported by source data.
- Implement alert overlap with report periods and dayparts.
- Implement basic threshold helpers.
- Implement source selection helpers for NWS narrative periods and broader context.
Deliverables
- A deterministic Daily Report forecast summary can be built from a fixture bundle.
- Daypart outputs are inspectable as JSON.
Tests
- Morning/midday/afternoon/evening grouping.
- Overnight grouping across midnight.
- Missing hourly data behavior.
- Boundary timestamps at daypart edges.
- Max/min and threshold calculations.
- Alert-period overlap behavior.
Done Criteria
- Forecast derivation is reliable enough to support a first report briefing package.
- No LLM or
scriptoriumintegration is required yet.
Stage 4: Report Registry and Valid-Period Resolution
Goal
Centralize report definitions, compatible comparison strategies, and valid-period behavior before building report-specific briefings.
Packages Introduced or Expanded
internal/reportinternal/timeutilinternal/app
Work Items
- Define report IDs and variants:
daily_todaydaily_tomorrowthree_dayweekendstorm
- Define report metadata structures.
- Define a report
Definitioncontract. - Implement a registry.
- Implement valid-period resolvers using the configured local timezone, default
Chicago, and half-open[start,end)intervals:- Today Daily Report: current local civil day,
[00:00, next 00:00). - Tomorrow Planning Brief: 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. - Storm Report: explicit
--startand--end.
- Today Daily Report: current local civil day,
- Parse manual storm period bounds from
YYYY-MM-DDTHH:MMin the configured timezone or RFC3339 timestamps with explicit offsets. - Define default prompt IDs:
weather.daily_reportweather.daily_reportfordaily_tomorrow; this prompt covers one civil day.weather.three_day_outlookweather.weekend_outlookweather.storm_report
- 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.
- Implement batch membership rules:
- Morning batch: Daily Today, 3-Day Outlook, Weekend Outlook except Sunday.
- Evening batch: Daily Tomorrow.
Deliverables
- App layer can resolve which reports should run for a command.
- Each report has a valid period independent of generation time.
- Report definitions map to prompt IDs and comparison strategies.
Tests
- Daily valid period for different generation times.
- Tomorrow valid period from evening generation.
- 3-Day period calculation from generation time.
- Weekend period calculation on Monday, Friday, Saturday, and Sunday.
- Storm manual period parsing and validation.
- Morning batch skips Weekend Outlook on Sunday.
- Registry lookup errors are actionable.
Done Criteria
- Report identity, period behavior, and compatible comparison rules are stable.
- Later stages can add builders without changing CLI semantics.
Stage 5: Daily Briefing Builder
Goal
Build the first complete report-specific briefing package without invoking the LLM.
Packages Introduced or Expanded
internal/briefinginternal/reportinternal/forecastinternal/app
Work Items
- Define common briefing metadata:
- Schema version.
- RunID.
- Report type.
- Variant.
- Generation time.
- Configured units and timezone.
- Valid start/end.
- Source location ID/name when provided by upstream.
- Source timestamps, SHA-256 hashes, and source warnings.
- Define the Daily Report briefing schema.
- Build Daily Report briefing content:
- Bottom-line inputs.
- Daypart summaries.
- Active or relevant alerts.
- Best/worst outdoor window inputs, if derivable.
- NWS narrative periods relevant to the day.
- Forecast discussion summary or selected text from the API data.
- Weather story summary or selected text when upstream support exists.
- Add JSON output for the briefing package.
- Add an app workflow that can generate the Daily briefing and write it to disk for inspection.
Deliverables
weatherreporter generate dailycan produce a Daily briefing JSON artifact without callingscriptorium.- Fixture-based output is stable enough for review.
Tests
- Daily briefing from representative fixture.
- Alerts included/excluded correctly.
- Source context selection.
- Source warnings included correctly.
- RunID included correctly.
- Empty or quiet-weather behavior.
- Snapshot metadata completeness.
Done Criteria
- The Daily briefing package is useful as prompt input.
- The app can produce the briefing artifact from real or fixture data.
Stage 6: Prompt Input Package and Scriptorium Render Preflight
Goal
Convert a briefing package into the structured data_package input expected by scriptorium prompts and validate prompt wiring without LLM generation.
Key References
docs/integrations/scriptorium.mddescribes the CLI contract forscriptorium render.
Packages Introduced or Expanded
internal/promptinputinternal/briefinginternal/reportinternal/adapters/scriptoriuminternal/app
Work Items
- Define prompt input data package schema structures.
- Build
data_packageJSON from report metadata, briefing content, source warnings, RunID, and an initially empty Recent Changes section. - Validate required data package fields before rendering.
- Write data package JSON to the workspace.
- Implement
scriptorium rendersupport in the adapter. - Invoke preflight as:
scriptorium render \
--prompt <prompt_id> \
--input data_package=<path> \
--format json
- Capture stdout and stderr separately.
- Persist render/preflight output for inspection.
- Treat render preflight as always-on before
scriptorium runfor MVP generated reports.
Deliverables
- Daily Report data package can be generated and written to a file.
- The data package is suitable for
scriptorium render --input data_package=<path>. - Prompt/input wiring can be checked without LLM execution.
Tests
- Data package generated from Daily briefing fixture.
- Missing required fields fail validation.
- JSON output is deterministic where practical.
- Adapter command construction for
scriptorium render. - Nonzero render exit handling.
- Always-on preflight behavior in the generation workflow.
Done Criteria
- The app can prepare and preflight a complete data package for a Daily Report.
- LLM rendering is the only missing step for the first end-to-end report.
Stage 7: Filesystem State Store and Metadata Baseline
Goal
Persist report artifacts and metadata in a durable, inspectable structure before the first LLM-generated report.
Packages Introduced or Expanded
internal/stateinternal/app
Work Items
- Define state store interface.
- Implement filesystem-backed store.
- Persist briefing snapshots.
- Persist prompt input data package files.
- Persist
scriptorium renderpreflight output. - Persist report metadata.
- Add RunID as an explicit metadata concept based on generation timestamp plus report ID.
- Name managed report files with the generation timestamp to avoid overwriting previous runs for the same valid period.
- Link valid period, RunID, briefing snapshot, data package, preflight output, rendered report, source warnings, and source hashes in metadata.
- Use atomic writes where practical.
- Implement lookup for prior comparable Daily snapshots.
- Keep paths narrow and predictable.
Deliverables
- Each Daily preflight run has associated metadata, RunID, briefing snapshot, data package, and render output.
- Prior comparable snapshot lookup works for Daily Reports.
Tests
- Atomic write behavior where feasible.
- Metadata round-trip.
- Snapshot path generation.
- Data package path generation.
- Preflight output path generation.
- Timestamped managed report path generation.
- RunID metadata behavior.
- Prior snapshot lookup.
- Narrow-path safety behavior.
Done Criteria
- Daily report preparation leaves enough state for inspection and future Recent Changes.
- 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.mddescribes the CLI contract for runningscriptoriumas a subprocess.
Packages Introduced or Expanded
internal/adapters/scriptoriuminternal/appinternal/state
Work Items
- Define
scriptorium.Runrequest/result types or extend the runner interface introduced for render preflight. - Implement subprocess execution with
exec.CommandContext. - Pass arguments without shell interpolation.
- Pass the prompt input data package with
--input data_package=<path>. - Invoke generation as:
scriptorium run \
--prompt <prompt_id> \
--input data_package=<path> \
--out <artifact_path>
- Capture stderr and stdout with reasonable limits.
- Apply timeout and cancellation.
- Return actionable errors for nonzero exits, including exit code
2, which can still produce output. - 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.mdproduces 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
2handling. - Timeout behavior.
- Always-on preflight before run.
- App workflow test using fake weather client and fake
scriptoriumrunner.
Done Criteria
- The first report can be generated end-to-end.
scriptoriumis isolated behind the adapter package.
Stage 9: Recent Changes for Daily Reports
Goal
Add structured comparison of Daily Report briefing snapshots and include meaningful changes in prompt input data packages.
Packages Introduced or Expanded
internal/changesinternal/stateinternal/promptinputinternal/app
Work Items
- Define change summary structures.
- Define threshold configuration.
- Implement Daily briefing comparison.
- Compare current snapshot to prior comparable snapshot.
- Detect meaningful changes, such as:
- Temperature shifts.
- Precipitation timing shifts.
- Precipitation probability category changes.
- Alert changes.
- Wind gust changes.
- Snow/ice/thunder risk changes.
- Add Recent Changes to the data package.
- Omit or minimize Recent Changes when no meaningful changes exist.
Deliverables
- Daily Report data packages include Recent Changes when appropriate.
- Daily Report generation persists current snapshot after comparison.
Tests
- No prior snapshot behavior.
- No meaningful changes behavior.
- Temperature threshold crossing.
- Precipitation timing shift.
- Alert added/removed behavior.
- Comparison uses valid period and compatible strategy, not just generation time.
Done Criteria
- 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.
Stage 10: Tomorrow Planning Brief
Goal
Add the evening Tomorrow Planning Brief using the Daily Report machinery where practical.
Packages Introduced or Expanded
internal/reportinternal/briefinginternal/changesinternal/app
Work Items
- Implement the
daily_tomorrowreport definition fully. - Reuse or specialize the Daily briefing builder for tomorrow's valid date.
- Add any tomorrow-specific planning fields, such as:
- Morning readiness note inputs.
- Commute/school/workday concerns.
- What may change overnight.
- Ensure comparison can find a prior compatible report covering the same valid local date.
- Implement
run eveningas Daily Tomorrow.
Deliverables
weatherreporter generate tomorrowworks end-to-end.weatherreporter run eveningworks.
Tests
- Tomorrow valid-period calculation.
- Tomorrow briefing uses the correct date.
- 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.
Done Criteria
- Evening look-ahead generation is reliable.
- Daily Today and Daily Tomorrow share logic without muddling their identities.
Stage 11: 3-Day Outlook
Goal
Add the 3-Day Outlook report using the same architecture.
Packages Introduced or Expanded
internal/reportinternal/briefinginternal/forecastinternal/changesinternal/app
Work Items
- Implement 3-Day valid-period resolution.
- Build a 3-Day briefing package.
- Summarize each day or partial day:
- Overall character.
- Temperature range.
- Precipitation/storm/winter/heat/wind risks.
- Best/worst windows if derivable.
- Relevant alerts.
- Attach broader NWS context, especially forecast discussion and weather story inputs when available.
- Implement 3-Day Recent Changes strategy.
- Add end-to-end generation.
Deliverables
weatherreporter generate three-dayproduces Markdown.- Morning batch can include the 3-Day Outlook.
Tests
- Three-day valid period from generation time.
- Daily aggregation across the 3-Day window.
- Alert overlap across multi-day period.
- Recent Changes across multi-day snapshots.
- Quiet-weather behavior.
Done Criteria
- 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
Goal
Add the Weekend Outlook with day-of-week-sensitive period behavior.
Packages Introduced or Expanded
internal/reportinternal/briefinginternal/forecastinternal/changesinternal/app
Work Items
- Implement Weekend valid-period resolution:
- Monday through Thursday: upcoming Saturday 00:00 through Monday 00:00.
- Friday:
max(generation time, Friday 18:00)through Monday 00:00. - Saturday: generation time through Monday 00:00.
- Sunday: normally not generated by the scheduled morning batch.
- Build Weekend briefing package.
- Emphasize planning fields:
- Best outdoor windows.
- Worst weather windows.
- Rain/storm timing.
- Heat/cold/wind comfort.
- Confidence and uncertainty inputs.
- Implement Weekend Recent Changes strategy.
- Add morning batch inclusion except Sunday.
Deliverables
weatherreporter generate weekendproduces Markdown.weatherreporter run morningincludes Weekend Outlook except Sunday.
Tests
- Weekend period on each day of the week.
- Saturday remaining-weekend behavior.
- Sunday skip behavior in morning batch.
- Recent Changes across narrowed valid periods.
- Outdoor-window derivation behavior.
Done Criteria
- Weekend Outlook works end-to-end and follows expected scheduling behavior.
Stage 13: Morning and Evening Batch Hardening
Goal
Make scheduled workflows reliable enough for unattended execution by cron, systemd timers, or another orchestrator.
Packages Introduced or Expanded
internal/appinternal/cliinternal/stateinternal/config
Work Items
- Finalize
run morningworkflow. - Finalize
run eveningworkflow. - Continue remaining independent reports after one report fails.
- Return nonzero from the CLI if any report failed.
- Add structured aggregate run summaries.
- Ensure each report run records enough metadata for troubleshooting.
- Add CLI flags for output directory and optional dry-run/data-package-only mode if desired.
- Add logging suitable for scheduled execution.
Deliverables
- Morning batch can generate Daily, 3-Day, and Weekend reports.
- Evening batch can generate Tomorrow Planning Brief.
- Failures are understandable from logs, metadata, and aggregate summaries.
Tests
- Morning batch report selection.
- Evening batch report selection.
- Partial failure continues independent reports.
- Aggregate nonzero exit behavior.
- Output path behavior.
- Dry-run or data-package-only behavior, if implemented.
Done Criteria
- The scheduled report system is ready for real daily use.
Stage 14: Manual Storm Report
Goal
Add manual Storm Report generation without building the automatic monitoring agent yet.
Packages Introduced or Expanded
internal/reportinternal/briefinginternal/forecastinternal/appinternal/changes, if needed
Work Items
- Implement Storm Report definition.
- Require explicit storm valid-period bounds via
--startand--end. - Build storm briefing package from:
- Active alerts.
- Forecast discussion.
- Weather story when available.
- Relevant hourly/daily periods.
- NWS narrative periods.
- Include storm-specific fields:
- Event headline inputs.
- Timing window.
- Hazards.
- Most likely scenario inputs.
- Reasonable worst-case inputs, if supported by source context.
- Confidence and uncertainty inputs.
- What to watch next.
- Add manual command:
weatherreporter generate storm --start <time> --end <time>
Deliverables
- Manual Storm Report generation works end-to-end.
- No automatic agent behavior is required.
Tests
- Storm briefing with active alerts.
- Storm briefing with forecast discussion but no active alert.
- Quiet/no-storm behavior.
- Manual period parsing and validation.
- Relevant source selection.
Done Criteria
- A user can manually generate a focused Storm Report when desired.
- The implementation reuses the same pipeline rather than creating a separate flow.
Stage 15: Inspection and Debugging Tools
Goal
Make generated artifacts easy to inspect and debug.
Packages Introduced or Expanded
internal/cliinternal/appinternal/state
Work Items
- Add inspection commands as needed:
- List recent reports.
- Show metadata for a report.
- Show prior comparable snapshot chosen for Recent Changes.
- Emit briefing JSON without rendering.
- Emit data package JSON without rendering.
- Show source warnings and provenance.
- Add clear paths to generated artifacts in command output.
- Ensure logs do not dump large weather payloads by default.
Deliverables
- Developers can inspect why a report was generated a certain way.
- Recent Changes comparison inputs are discoverable.
- Source warnings are discoverable.
Tests
- Inspection command behavior with fixture state.
- Missing artifact errors.
- Metadata lookup behavior.
- Source warning display behavior.
Done Criteria
- Debugging a bad report does not require stepping through the whole workflow manually.
Stage 16: Future Storm Monitoring Agent
Goal
Add automatic storm-event evaluation only after scheduled reports and manual storm reports are stable.
Packages Introduced or Expanded
Potentially:
internal/stormor expandedinternal/report/internal/briefinginternal/adapters/scriptoriumor a separate evaluator prompt adapterinternal/stateinternal/app
Work Items
- Implement deterministic candidate detection.
- Define storm candidate structures.
- Use source signals such as:
- Active alerts.
- Forecast discussion hazard wording.
- Weather Story emphasis when available.
- Hourly/daily threshold crossings.
- Material forecast changes toward higher impact.
- Add an LLM event evaluator through
scriptoriumor a future native LLM adapter. - Track storm lifecycle state:
nonemonitoringactive_reportescalateddeescalatingresolved
- Generate or update Storm Reports only when warranted.
- Avoid noisy report generation for ordinary low-impact thunder chances.
Deliverables
weatherreporter evaluate stormcan decide whether a Storm Report is warranted.- Event lifecycle state is persisted.
- Storm Report updates are generated only for meaningful changes.
Tests
- Candidate detection thresholds.
- Noisy/non-event suppression.
- Alert-triggered escalation.
- Lifecycle transitions.
- Evaluator failure behavior.
Done Criteria
- Automatic storm monitoring is useful and not spammy.
- Manual Storm Report generation remains available.
Suggested First Implementation Milestone
The first meaningful milestone should be:
weatherreporter generate daily --out ./daily.md
This command should:
- Load config.
- Fetch weather data from the configured endpoint.
- Build a Daily briefing package.
- Build a prompt input data package.
- Run
scriptorium renderpreflight. - Invoke
scriptorium run. - Write Markdown output.
- 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 input, and adapter issues earlier than a broad but shallow implementation.
Suggested Second Implementation Milestone
The second milestone should be:
weatherreporter run morning
weatherreporter run evening
At this point, the app should support:
- Daily Today.
- Daily Tomorrow.
- 3-Day Outlook.
- Weekend Outlook.
- Recent Changes for all scheduled report types.
- Filesystem state and metadata.
- Reliable scheduled execution.
- Partial-failure continuation with nonzero aggregate exit status.
Suggested Third Implementation Milestone
The third milestone should be:
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.
Non-Goals for the Initial Prototype
Do not implement these in the initial prototype unless required by real use:
- Native LLM client inside
weatherreporter. - Daemon mode.
- Automatic storm-monitoring agent.
- Database-backed state.
- Multi-location weatherreporter selection.
- Multi-user authorization.
- Public HTTP API.
- Complex plugin system.
- Markdown diffing for Recent Changes.
- Raw unbounded weather payloads sent directly to prompts.
Final Implementation Notes
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:
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.