Refresh README and operations guide

This commit is contained in:
2026-07-31 01:00:21 +00:00
parent ad3b788f8c
commit 0c27fab384
2 changed files with 108 additions and 234 deletions

View File

@@ -1,10 +1,10 @@
# weatherreporter # weatherreporter
`weatherreporter` is a Go application for preparing human-facing weather Weatherreporter is a Go CLI that turns normalized weather data into managed,
reports from normalized forecast data. It builds JSON module snapshots, passes human-facing Markdown reports.
YAML prompt data packages to `scriptorium`, and keeps inspectable artifacts
under a local workspace. It can also upload successfully generated managed It provides repeatable reports with inspectable local artifacts, so operators
Markdown reports to a configured `distributor` HTTP upload endpoint. can review what was collected and generated for every run.
## Quickstart ## Quickstart
@@ -12,11 +12,14 @@ Markdown reports to a configured `distributor` HTTP upload endpoint.
weatherreporter generate today --out ./today.md weatherreporter generate today --out ./today.md
``` ```
Configure a Weather API endpoint first; see the
[configuration reference](docs/config.md).
## Documentation ## Documentation
- [CLI reference](docs/cli.md) - [CLI reference](docs/cli.md)
- [Configuration reference](docs/config.md) - [Configuration reference](docs/config.md)
- [Operations guide](docs/operations.md) - [Operations guide](docs/operations.md)
- [Troubleshooting](docs/troubleshooting.md) - [Troubleshooting](docs/troubleshooting.md)
- [Architecture policy](docs/policy/architecture.md)
- [Development guide](docs/development.md) - [Development guide](docs/development.md)
- [Architecture policy](docs/policy/architecture.md)

View File

@@ -1,77 +1,54 @@
# Weatherreporter Operations # Weatherreporter Operations
This guide covers normal operation, generated artifacts, inspection, recovery, This guide covers normal operation, managed workspace state, inspection,
and operational caveats. For symptom-specific diagnosis, see recovery, and operational caveats. See the [CLI reference](cli.md) for complete
command syntax and the [configuration reference](config.md) for fields,
defaults, and notification templates. For symptom-based diagnosis, see
[Troubleshooting](troubleshooting.md). [Troubleshooting](troubleshooting.md).
## Normal Workflow ## Normal Operation
Generation commands: After configuring a Weather API endpoint, generate one report:
```text ```sh
weatherreporter generate daily --date 2026-05-29 weatherreporter generate today --out ./today.md
weatherreporter generate today
weatherreporter generate tomorrow
weatherreporter generate hourly
weatherreporter generate three-day
weatherreporter generate weekend
weatherreporter generate storm --start 2026-05-29T18:00 --end 2026-05-30T06:00
``` ```
Generation commands resolve a report period, collect a Weather API bundle, A generation collects weather data, resolves the report period, builds and
build a rich JSON module snapshot, build a curated YAML prompt input data persists the module snapshot and prompt data package, runs Scriptorium
package, run `scriptorium render`, and write managed artifacts under the preflight, then produces the managed Markdown report. Daily, Today, Tomorrow,
configured workspace. Markdown-path reports then run `scriptorium run` directly and Hourly reports additionally persist generated-text artifacts, validate the
to the managed Markdown report path. structured generated text, and render Markdown from the validated text and
deterministic values.
`generate daily`, `generate today`, `generate tomorrow`, and `generate hourly` The managed report and its final metadata are saved before single-report
use the generated-text-template workflow. They run structured `scriptorium run` Distributor notification is attempted. `--out` writes an extra operator copy;
to raw GeneratedText JSON, validate the structured text, save a render context, it never changes the managed report or upload source. A successful generate
and render the managed Markdown report from embedded templates. `generate command prints its summary to stdout unless `--quiet` is used.
daily` requires `--date YYYY-MM-DD` for the selected local civil day.
`generate today` covers the selected or current local civil day. `generate
hourly` covers the six-hour rolling period from generation time in the
effective report timezone and is not included in `run morning` or
`run evening`.
When distributor notification is enabled, weatherreporter uploads the managed Run a scheduled batch with the same configured collection:
Markdown report after report rendering succeeds and final metadata is saved.
`--out PATH` writes an extra Markdown copy for generated reports; it is not used
as the distributor upload source. Generate commands emit a compact JSON summary
to stdout by default. Use `--quiet` to suppress successful stdout for cron jobs
or other schedulers that only need nonzero exits and external logs.
Batch commands: ```sh
weatherreporter run morning --out-dir ./reports
```text
weatherreporter run morning
weatherreporter run evening
``` ```
`run morning` generates Today Report, Tomorrow Report, and a dated Daily Report Each batch collects once before it plans reports. Morning runs Today, Tomorrow,
for each later future local civil day with complete hourly forecast coverage. and every eligible dated Daily Report; evening runs Tomorrow and the same
`run evening` generates Tomorrow Report and the same eligible future Daily eligible Daily Reports. Eligible Daily dates begin after tomorrow and require
reports. Future Daily expansion starts with the day after tomorrow. A Daily complete hourly coverage for their entire local civil day. A batch continues
report is eligible only when the collected hourly forecast contains every after an individual report fails and returns an aggregate failure when any
hourly period for that local civil day; partial days are skipped. Batch commands report or batch notification fails.
collect weather data once before planning, and a collection failure stops the
batch before any report is generated.
After planning succeeds, batch commands print a JSON summary to stdout, write `--out-dir` writes extra copies such as `today.md`, `tomorrow.md`, and
compact per-report status lines to stderr, continue independent reports after `daily-YYYY-MM-DD.md`. These copies are never upload sources. Batch report
one report fails, and return nonzero when any report failed. Batch commands do copies and notification behavior are summarized in the CLI result; use the
not upload each report independently. When distributor notification and batch [CLI reference](cli.md) for its exact JSON and stderr contract.
notification are enabled, weatherreporter uploads one distributor bundle only
after every planned report succeeds. If any report fails, the batch upload is
skipped for the whole batch. `--out-dir PATH` writes extra Markdown copies
using report default filenames such as `today.md` and `tomorrow.md`; dynamic
Daily copies use `daily-YYYY-MM-DD.md`. These copies are not used as
distributor upload sources. Use `--quiet` to suppress successful batch summary
and status output; failures still return nonzero.
## Filesystem Layout ## Managed Workspace
The default workspace root is `workspace`. The default workspace root is `workspace`. Artifact paths use the report
definition's artifact group, the valid-period start date in the effective
timezone, and the RunID:
```text ```text
workspace/ workspace/
@@ -91,195 +68,89 @@ workspace/
notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json
``` ```
Managed artifact filenames use the artifact kind and RunID, so repeated runs The generated-text and render-context artifacts are written only by Daily,
for the same valid period do not overwrite each other. The date directory is Today, Tomorrow, and Hourly reports. A report's metadata links the module
the valid-period start date in the effective report timezone. Generated-text snapshot, data package, preflight artifact, managed report, and any available
artifacts are written only for Daily, Today, Tomorrow, and Hourly reports. generated-text or single-report notification artifact. Batch notification
artifacts are separate batch-level records under `notifications/batches`.
## RunID And Metadata RunIDs begin with the UTC generation timestamp and report ID. A Daily RunID
also contains its local valid date so multiple Daily reports in one batch have
RunIDs are based on generation time plus report ID. Reports that can be different managed paths. Batch notification RunIDs contain the UTC batch start
generated more than once in a single command may append a report-specific timestamp and batch name.
disambiguator. Daily appends the local valid date so multiple dynamic Daily
reports in one batch have distinct managed artifacts:
```text
20260529T100000.123456789Z_daily_2026-05-31
20260529T100000.123456789Z_today
```
Batch notification RunIDs use the batch start timestamp plus the batch command
name:
```text
20260529T100000.123456789Z_morning
20260529T220000.123456789Z_evening
```
Each generated report writes metadata that links:
- RunID, report ID, variant, and prompt ID
- generation time, timezone, and valid period
- source location, source hashes, and source warnings
- module snapshot path
- prompt input data package path
- preflight output path
- managed Markdown report path
- generated text schema ID and generated-text artifact paths for
generated-text-template reports
- distributor notification debug artifact path, when notification is attempted
Batch summaries include report status, error text when applicable, valid
period, and known artifact paths for each attempted report. Single-report
notification fields on report items are empty for batch commands. When a batch
notification is attempted, skipped, or fails, the summary includes one
top-level `notification` object with fields such as `status`, `reason`,
`runId`, `pipelineId`, `bundleId`, `idempotencyKey`, `path`,
`includedReports`, and `error`.
## Distributor Notification ## Distributor Notification
Distributor notification is configured with `notify.distributor` and is When `notify.distributor.enabled` is enabled, a successful `generate`
disabled by default. For `generate <report>`, weatherreporter uploads the uploads only the managed Markdown report after final metadata has been saved.
managed Markdown report path recorded in the report result and metadata. That The extra copy from `--out` is never uploaded. A notification attempt writes
single source file is mapped to report-specific bundle paths. Extra copies a redacted debug artifact at
written by `--out` or `--out-dir` are operator conveniences only. `notifications/<artifact_group>/<YYYY-MM-DD>/distributor.<run_id>.json`; its
path is then recorded in report metadata.
For `run morning` and `run evening`, per-report notification is suppressed. If Batches suppress per-report notification. When both Distributor and its batch
`notify.distributor.enabled` and `notify.distributor.batch.enabled` are both notification are enabled, Weatherreporter submits one multi-report upload after
true, the batch uploads once after all reports finish successfully. The upload every planned report succeeds. If any report fails, it records a top-level
contains one file mapping set per included report. Each mapping uses the `skipped` notification with reason `one or more reports failed` and does not
managed Markdown report as the source and report-specific path templates for call Distributor. If batch notification is disabled, a batch does not fall back
that report. All rendered bundle paths across the batch must be unique. If any to individual uploads.
report fails, weatherreporter records a top-level
notification status of `skipped` with reason `one or more reports failed` and
does not call distributor. If batch notification is disabled, run commands do
not fall back to per-report uploads.
The rendered pipeline ID selects the configured distributor `http_upload` A batch notification attempt writes
workflow. The default bundle ID is a stable logical source identity derived from `notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json`.
producer name, location ID, and report ID: A notification failure makes the batch fail but does not change successful
individual report items into failed items. The debug artifacts contain rendered
identifiers, managed source and bundle paths, upload and status results, and
redacted errors; they do not contain tokens.
```text ## Inspecting Stored Runs
weatherreporter.{location_id}.{report_id}
```
The default single-report idempotency key appends RunID to the rendered bundle Inspection is read-only: it neither collects weather data nor invokes
ID so each report generation has a distinct retry identity. The default bundle Scriptorium or Distributor. Start by finding a RunID:
path uses the valid-period start date, artifact group, and RunID. Batch bundle
IDs default to `weatherreporter.{location_id}.{batch}`, and batch idempotency
keys default to `{bundle_id}.{batch_run_id}`. Distributor owns destination
merge, retention, and derived snapshot behavior such as `latest`. For Daily,
the default report ID and artifact group values are both `daily`, and the
default output filename value is `daily.md`. For Today, the default report ID
and artifact group values are both `today`, and the batch output filename value
is `today.md`.
Single-report notification happens after final metadata save for generated ```sh
reports. Batch notification happens after all planned reports have finished and
only when all report generations succeeded. Collection, module snapshot,
data-package, render preflight, Scriptorium run, generated-text validation,
template rendering, and metadata-save failures do not trigger notification. A
single-report notification failure fails that report. A batch notification
failure makes the batch return nonzero and increments the aggregate failure
count, but individual report items remain succeeded.
Each notification attempt writes a debug artifact under `notifications/`.
Single-report artifacts live under
`notifications/<artifact_group>/<YYYY-MM-DD>/distributor.<run_id>.json`. Batch
artifacts live under
`notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json`,
where the date directory is the batch start date in the effective report
timezone. The artifact records the rendered pipeline ID, bundle ID,
idempotency key, managed source paths, bundle-relative paths, bundle created
timestamp, accepted upload response, and the latest distributor run status
response when available. Weatherreporter polls status until distributor reports
`succeeded` or `failed`, or until the configured notification timeout expires.
The run status includes the distributor status, error text, and raw run report
JSON, which can show actions such as `replace_older`, `skip_same`,
`skip_destination_newer`, or `failed`. Token values are not written.
Weatherreporter is responsible for selecting the managed Markdown report,
constructing a source bundle, and submitting it to the configured distributor
HTTP endpoint. Distributor remains responsible for destination routing,
publication, and any downstream Markdown-to-HTML transformation. Distributor
leaves destination files alone when they are not tracked by a newly uploaded
bundle, so existing uploaded dated report paths can remain available.
## Inspection
Inspection commands read existing workspace artifacts and emit JSON to stdout.
They do not collect weather data or run `scriptorium`.
```text
weatherreporter inspect reports --limit 10 weatherreporter inspect reports --limit 10
weatherreporter inspect metadata RUN_ID weatherreporter inspect metadata RUN_ID
weatherreporter inspect modules RUN_ID
weatherreporter inspect data-package RUN_ID
weatherreporter inspect prior RUN_ID
weatherreporter inspect sources RUN_ID
``` ```
Use `inspect reports` to find RunIDs and artifact paths. Use | Command | Reads |
`inspect metadata` to see the artifact links recorded for a run. Use | --- | --- |
`inspect modules` to review the persisted ordered module snapshot with rich | `inspect reports` | Metadata files under the workspace snapshots tree. |
template-facing values, and `inspect data-package` to review the curated prompt | `inspect metadata RUN_ID` | Metadata located by RunID. |
package passed to Scriptorium. Use `inspect prior` to see the prior comparable | `inspect modules RUN_ID` | The module snapshot path recorded in metadata. |
snapshot selected for Recent Changes, or `null` when none exists. Use | `inspect data-package RUN_ID` | The data-package path recorded in metadata. |
`inspect sources` to review source provenance and warnings without dumping full | `inspect prior RUN_ID` | The run metadata, then compatible earlier metadata for its comparison policy. |
weather payloads. | `inspect sources RUN_ID` | Source provenance and warnings in the run metadata. |
## Recent Changes A missing snapshots directory produces no listed reports. An unknown or empty
RunID is an error; use `inspect reports` to obtain a valid value.
Recent Changes are computed from structured module snapshots, not rendered
Markdown or YAML text.
Daily Report compares with prior Daily Report snapshots for the same valid
local date. Today Report compares with prior Today Report snapshots for the
same valid local date. Tomorrow Report compares with prior Tomorrow Report
snapshots for the same valid local date. 3-Day Outlook compares with prior
compatible 3-Day snapshots for the same valid local date. Weekend Outlook
compares with prior compatible Weekend snapshots for the same weekend window.
Hourly Report and Storm Report leave Recent Changes empty.
When no prior comparable snapshot exists, or no configured threshold is crossed,
`recentChanges.items` is empty.
## Recovery ## Recovery
A failed generation run may still leave useful artifacts: Keep the workspace when a run fails: artifacts reached before the failure
remain available where they can be safely persisted.
- If `scriptorium render` returns a result with a nonzero exit code, the - A preflight failure can leave the preflight artifact and metadata.
preflight JSON and metadata are written for inspection. - A report-generation failure can leave the managed report, module snapshot,
- If `scriptorium run` exits nonzero after writing a report, the managed report data package, and metadata.
and metadata remain available. - A generated-text failure can leave raw text, the structured run result, or a
- Generated-text failures for Daily, Today, Tomorrow, and Hourly reports preserve validated generated-text and render-context artifact, depending on where it
available intermediate artifacts, such as the structured run result, raw stopped.
generated-text JSON, validated generated text, and render context. Metadata - A single-report notification failure preserves the report and final metadata,
links those paths when it can be safely written. including its notification artifact when it was written.
- If single-report distributor notification fails, report artifacts and final - A batch notification failure preserves each report's artifacts and adds the
metadata remain available, but the report command returns nonzero. top-level batch notification artifact.
- If batch distributor notification fails, report artifacts and final metadata
remain available, the top-level batch notification links the debug artifact,
and the batch command returns nonzero.
- For batch commands, inspect the stdout JSON summary first, then inspect the
artifact paths for each failed report or the top-level notification path.
For a bad report, start with: Use the RunID from the action summary with the inspection commands above. For
a batch failure, inspect the summary first, then inspect the affected report
```text RunIDs or the batch notification path. Do not remove the whole workspace as a
weatherreporter inspect metadata RUN_ID first response; retain it until the failure is understood.
weatherreporter inspect sources RUN_ID
weatherreporter inspect modules RUN_ID
weatherreporter inspect data-package RUN_ID
weatherreporter inspect prior RUN_ID
```
## Operational Caveats ## Operational Caveats
- The application uses one configured Weather API endpoint. - Workspace files, generated reports, and Scriptorium stderr can contain
- The application writes local filesystem state only. sensitive operational context. Set appropriate filesystem permissions and do
- The application does not implement resume, cleanup, archive, remote storage, not publish them unintentionally.
daemon operation, or automatic storm monitoring. - Weatherreporter uses one configured Weather API endpoint and local workspace
- Generated reports and Scriptorium stderr can contain sensitive operational state.
context. Store workspace artifacts with appropriate filesystem permissions. - It does not provide automatic resume, cleanup, archival, remote state, daemon
operation, or automatic storm monitoring.