Refresh README and operations guide
This commit is contained in:
15
README.md
15
README.md
@@ -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)
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user