Document stateless output operations
This commit is contained in:
124
docs/cli.md
124
docs/cli.md
@@ -1,17 +1,17 @@
|
||||
# Weatherreporter CLI
|
||||
|
||||
`weatherreporter` generates weather reports, runs report batches, and inspects
|
||||
artifacts already stored in its workspace.
|
||||
`weatherreporter` generates Markdown weather reports and runs report batches.
|
||||
It has no command for inspecting prior runs or application-owned state.
|
||||
|
||||
## Shortest Useful Command
|
||||
|
||||
```sh
|
||||
weatherreporter generate today --out ./today.md
|
||||
weatherreporter generate today
|
||||
```
|
||||
|
||||
The command uses the configured Weather API and writes an extra Markdown copy
|
||||
at `./today.md`. See the [configuration reference](config.md) to supply the
|
||||
required Weather API endpoint.
|
||||
The command uses the configured Weather API and writes an atomically replaced
|
||||
`today.md` in the current directory. See the [configuration reference](config.md)
|
||||
to supply the required Weather API endpoint.
|
||||
|
||||
## Commands And Usage
|
||||
|
||||
@@ -24,12 +24,6 @@ weatherreporter generate tomorrow [--config PATH] [--units VALUE] [--tz NAME] [-
|
||||
weatherreporter generate hourly [--config PATH] [--units VALUE] [--tz NAME] [--out PATH] [--llm-debug-dir PATH] [--quiet]
|
||||
weatherreporter run morning [--config PATH] [--units VALUE] [--tz NAME] [--out-dir PATH] [--llm-debug-dir PATH] [--quiet]
|
||||
weatherreporter run evening [--config PATH] [--units VALUE] [--tz NAME] [--out-dir PATH] [--llm-debug-dir PATH] [--quiet]
|
||||
weatherreporter inspect reports [--config PATH] [--limit N]
|
||||
weatherreporter inspect metadata [--config PATH] RUN_ID
|
||||
weatherreporter inspect modules [--config PATH] RUN_ID
|
||||
weatherreporter inspect data-package [--config PATH] RUN_ID
|
||||
weatherreporter inspect prior [--config PATH] RUN_ID
|
||||
weatherreporter inspect sources [--config PATH] RUN_ID
|
||||
```
|
||||
|
||||
`weatherreporter --version` prints the version embedded in the executable.
|
||||
@@ -38,69 +32,78 @@ builds report `development`.
|
||||
|
||||
| Command | Contract |
|
||||
| --- | --- |
|
||||
| `generate daily` | Requires `--date YYYY-MM-DD`; the date is interpreted in the effective report timezone. |
|
||||
| `generate today` | Accepts an optional `--date YYYY-MM-DD`; without it, the current local date in the effective report timezone is used. |
|
||||
| `generate tomorrow` | Uses the next local civil day and accepts the common generate flags. |
|
||||
| `generate hourly` | Covers the next six hours in the effective report timezone. It does not accept `--date`, `--hours`, or `--duration`. |
|
||||
| `run morning` and `run evening` | Run their defined report batches. `--out-dir` writes extra Markdown copies; `--out` is not accepted. |
|
||||
| `generate daily` | Requires `--date YYYY-MM-DD`; the date is interpreted in the effective report timezone. Its default filename is `daily-YYYY-MM-DD.md`. |
|
||||
| `generate today` | Accepts an optional `--date YYYY-MM-DD`; without it, the current local date in the effective report timezone is used. Its default filename is `today.md`. |
|
||||
| `generate tomorrow` | Uses the next local civil day and writes `tomorrow.md` by default. |
|
||||
| `generate hourly` | Covers the next six hours in the effective report timezone and writes `hourly.md` by default. It does not accept `--date`, `--hours`, or `--duration`. |
|
||||
| `run morning` and `run evening` | Run their defined report batches and write each selected report beneath the current directory unless `--out-dir` selects another directory. `--out` is not accepted. |
|
||||
|
||||
`generate` accepts the four report command names shown above. `run` accepts
|
||||
only `morning` and `evening`. Batch membership, workspace artifacts, and
|
||||
notification sequencing are described in the [operations guide](operations.md).
|
||||
only `morning` and `evening`. Batch membership and notification ordering are
|
||||
described in the [operations guide](operations.md).
|
||||
|
||||
## Output, Errors, And Quiet Mode
|
||||
|
||||
For `generate`, the default output is the report's filename in the current
|
||||
directory. `--out PATH` selects one output file instead. A relative path is
|
||||
resolved from the current directory; an absolute path is used as given. For a
|
||||
batch, the equivalent default is the current directory and `--out-dir PATH`
|
||||
selects its output directory. Successful summaries always report the resulting
|
||||
absolute `outputPath` values.
|
||||
|
||||
Outputs are written atomically. A generation, rendering, write, or cancellation
|
||||
failure before publication leaves an existing destination unchanged. A
|
||||
notification failure occurs after publication, so the newly written output
|
||||
remains available.
|
||||
|
||||
Action commands (`generate` and `run`) write a JSON summary to stdout unless
|
||||
`--quiet` is set. `run` also writes compact per-report and batch status lines
|
||||
to stderr. A pre-run error, such as an invalid flag, missing required argument,
|
||||
or configuration-load failure, produces no partial JSON summary. When an action
|
||||
fails after it has produced a result, its summary has `"status": "failed"` and
|
||||
an `error` field.
|
||||
or configuration-load failure, produces no partial JSON summary. When an
|
||||
action fails after it has produced a result, its summary has `"status": "failed"`
|
||||
and an `error` field.
|
||||
|
||||
`--quiet` is supported by action commands only. It suppresses action summaries
|
||||
and routine batch status output; it does not suppress command errors.
|
||||
|
||||
Inspection commands always write their requested JSON value to stdout and do
|
||||
not accept `--quiet`.
|
||||
|
||||
### Generate Summary
|
||||
|
||||
A generate summary always identifies the command, report, run, generation
|
||||
time, valid period, and status:
|
||||
A generate summary identifies the command, report, run, generation time, valid
|
||||
period, prompt version, timezone, and status. Successful output has an absolute
|
||||
`outputPath`:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "generate",
|
||||
"reportId": "today",
|
||||
"reportName": "Today Report",
|
||||
"promptId": "weather.today_generated_text",
|
||||
"promptVersion": "2.0.0",
|
||||
"runId": "20260529T120000.000000000Z_today",
|
||||
"status": "succeeded",
|
||||
"generatedAt": "2026-05-29T12:00:00Z",
|
||||
"validPeriod": {
|
||||
"start": "2026-05-29T00:00:00-05:00",
|
||||
"end": "2026-05-30T00:00:00-05:00"
|
||||
}
|
||||
"timezone": "America/Chicago",
|
||||
"outputPath": "/srv/weather/today.md"
|
||||
}
|
||||
```
|
||||
|
||||
When available, the summary also includes `reportPath`, `metadataPath`,
|
||||
`dataPackagePath`, `preparationPath`, `executionPath`, `generatedTextRawPath`,
|
||||
`generatedTextPath`, `renderContextPath`, and `llmDebugPath`. `outputPath` is included only
|
||||
when `--out` wrote an extra copy. Distributor notification, when attempted,
|
||||
adds `notificationPath` and may add a compact `notification` object.
|
||||
When available, the summary also includes the effective `profileId`,
|
||||
`backendId`, `modelName`, `sourceWarnings`, `validationStatus`, requested
|
||||
`llmDebugPath`, and compact Distributor `notification` result. It does not
|
||||
include historical or transient artifact paths such as metadata, prompt input,
|
||||
raw generated text, render context, or notification receipts.
|
||||
|
||||
### Run Summary And Stderr
|
||||
|
||||
A run summary contains `command`, `batch`, `status`, `startedAt`, `finishedAt`,
|
||||
`total`, `succeeded`, `failed`, and a `reports` array. It may also contain a
|
||||
top-level `notification` object and `error`. Batch status is `failed` if any
|
||||
report or the batch notification fails.
|
||||
`total`, `succeeded`, `failed`, and a `reports` array. Each report item includes
|
||||
its identity, status, effective profile and model details when available,
|
||||
source warnings, validation status, and absolute `outputPath` after publication.
|
||||
The top-level summary may also contain a batch `notification` object and
|
||||
`error`. Batch status is `failed` if any report or the batch notification fails.
|
||||
|
||||
Without `--quiet`, batch status lines use this form:
|
||||
|
||||
```text
|
||||
report=today status=succeeded output="reports/today.md"
|
||||
report=today status=succeeded output="/srv/weather/reports/today.md"
|
||||
batch=morning total=2 succeeded=2 failed=0
|
||||
```
|
||||
|
||||
@@ -112,12 +115,11 @@ batch=morning total=2 succeeded=2 failed=0
|
||||
| `--config PATH` | all commands | Load `PATH` instead of `/usr/local/etc/weatherreporter/config.yml`. |
|
||||
| `--units VALUE` | `generate`, `run` | Override `weather_api.units` for this command. |
|
||||
| `--tz NAME` | `generate`, `run` | Override `weather_api.timezone` for this command. |
|
||||
| `--out PATH` | every `generate` command | Write an extra Markdown report copy. |
|
||||
| `--llm-debug-dir PATH` | every `generate` and `run` command | Write requested sensitive prompt diagnostics outside the managed workspace. The path must be absolute. |
|
||||
| `--out-dir PATH` | `run morning`, `run evening` | Write extra Markdown report copies in `PATH`. |
|
||||
| `--out PATH` | every `generate` command | Write the report to this file instead of its current-directory default. |
|
||||
| `--llm-debug-dir PATH` | every `generate` and `run` command | Write requested sensitive prompt diagnostics under this absolute path. |
|
||||
| `--out-dir PATH` | `run morning`, `run evening` | Write batch reports beneath this directory instead of the current directory. |
|
||||
| `--quiet` | `generate`, `run` | Suppress action summaries and routine batch status output. |
|
||||
| `--date YYYY-MM-DD` | `generate daily`, `generate today` | Required for Daily; optional for Today. |
|
||||
| `--limit N` | `inspect reports` | Maximum runs to list. Defaults to `20`; `0` means no limit. |
|
||||
|
||||
Distributor notification is configured through `notify.distributor`; there are
|
||||
no Distributor-specific CLI flags. See the [configuration reference](config.md).
|
||||
@@ -125,33 +127,9 @@ no Distributor-specific CLI flags. See the [configuration reference](config.md).
|
||||
## Invocation Examples
|
||||
|
||||
```sh
|
||||
weatherreporter generate daily --date 2026-05-29 --out ./daily.md
|
||||
weatherreporter generate today --date 2026-05-29 --out ./today.md
|
||||
weatherreporter generate hourly --out ./hourly.md
|
||||
weatherreporter generate daily --date 2026-05-29
|
||||
weatherreporter generate today --out ./reports/today.md
|
||||
weatherreporter generate hourly --out /srv/weather/hourly.md
|
||||
weatherreporter generate today --llm-debug-dir /var/tmp/weatherreporter-debug
|
||||
weatherreporter run morning --out-dir ./reports --llm-debug-dir /var/tmp/weatherreporter-debug
|
||||
```
|
||||
|
||||
## Inspection Commands
|
||||
|
||||
```sh
|
||||
weatherreporter inspect reports --limit 10
|
||||
weatherreporter inspect metadata 20260529T100000.000000000Z_today
|
||||
weatherreporter inspect modules 20260529T100000.000000000Z_today
|
||||
weatherreporter inspect data-package 20260529T100000.000000000Z_today
|
||||
weatherreporter inspect prior 20260529T100000.000000000Z_today
|
||||
weatherreporter inspect sources 20260529T100000.000000000Z_today
|
||||
```
|
||||
|
||||
| Command | JSON returned |
|
||||
| --- | --- |
|
||||
| `inspect reports` | Recent generated runs, including artifact paths and source-warning counts. |
|
||||
| `inspect metadata RUN_ID` | Persisted metadata for the run. |
|
||||
| `inspect modules RUN_ID` | The run's persisted ordered module snapshot. |
|
||||
| `inspect data-package RUN_ID` | The run's persisted prompt data package. |
|
||||
| `inspect prior RUN_ID` | Prior comparable snapshot metadata, or `null` when none exists. |
|
||||
| `inspect sources RUN_ID` | Source provenance and source warnings without full weather payloads. |
|
||||
|
||||
Inspection is read-only: it does not collect weather data or invoke Promptkit.
|
||||
See the [operations guide](operations.md) for artifact lifecycle
|
||||
and recovery.
|
||||
|
||||
@@ -13,8 +13,8 @@ explicit `--config PATH` must exist. Values are applied in this order:
|
||||
2. the configuration file, when present; and
|
||||
3. the `--units` and `--tz` command-line overrides.
|
||||
|
||||
Environment variables do not override configuration fields. Output flags write
|
||||
extra report copies for a command and do not change configuration.
|
||||
Environment variables do not override configuration fields. Output flags select
|
||||
operator-owned destinations for one command and do not change configuration.
|
||||
|
||||
## Maintained Examples
|
||||
|
||||
@@ -129,7 +129,7 @@ The default paths are:
|
||||
| `tomorrow` | `daily/{valid_start_date}/{run_id}.md`, `daily/{valid_start_date}/index.md`, `tomorrow/index.md` |
|
||||
|
||||
See the [operations guide](operations.md) for notification timing, uploaded
|
||||
artifact selection, and failure handling.
|
||||
output selection, and failure handling.
|
||||
|
||||
### `missing_source`
|
||||
|
||||
@@ -160,7 +160,7 @@ individual `generate` or `run` command when explicitly needed.
|
||||
`profile` selects an ID; `profile_file` and `profile_dir` supply definitions.
|
||||
They are separate decisions. An explicit `profile` applies to every selected
|
||||
report. Otherwise Hourly selects `weather-light`, while Daily, Today, and
|
||||
Tomorrow select `weather-balanced` through their exact `1.1.0` prompt
|
||||
Tomorrow select `weather-balanced` through their exact `2.0.0` prompt
|
||||
definitions.
|
||||
|
||||
Promptkit resolves a selected profile definition from a test or embedding
|
||||
@@ -179,21 +179,6 @@ model before use. An alternative profile may use `backend: local`; in that
|
||||
case `promptkit.local.endpoint` supplies the conventional local backend
|
||||
endpoint.
|
||||
|
||||
### `workspace`
|
||||
|
||||
| Field | Default |
|
||||
| --- | --- |
|
||||
| `root` | `workspace` |
|
||||
| `snapshots_dir` | `snapshots` |
|
||||
| `reports_dir` | `reports` |
|
||||
| `data_packages_dir` | `data-packages` |
|
||||
| `preflight_dir` | `preflight` |
|
||||
| `notifications_dir` | `notifications` |
|
||||
|
||||
`workspace.root` is required. Each workspace subdirectory must be a relative
|
||||
path that stays within the root. See the [operations guide](operations.md) for
|
||||
the managed workspace layout and lifecycle.
|
||||
|
||||
### `dayparts`
|
||||
|
||||
`dayparts` is a non-empty list of named local-time windows used in forecast
|
||||
@@ -202,18 +187,6 @@ derivation. Every item needs `name`, `start`, and `end`; start and end use
|
||||
(`06:00`–`10:00`), `midday` (`10:00`–`15:00`), `afternoon`
|
||||
(`15:00`–`17:00`), and `evening` (`17:00`–`24:00`).
|
||||
|
||||
### `recent_change`
|
||||
|
||||
| Field | Default |
|
||||
| --- | --- |
|
||||
| `temperature_degrees` | `5` |
|
||||
| `precip_probability_points` | `20` |
|
||||
| `wind_gust_miles_per_hour` | `10` |
|
||||
| `precip_timing_shift_minutes` | `120` |
|
||||
|
||||
These thresholds control when Recent Changes are included in prompt input for a
|
||||
prior comparable module snapshot.
|
||||
|
||||
### `reports`
|
||||
|
||||
`reports` optionally overrides a report's ordered deterministic modules and
|
||||
|
||||
@@ -21,16 +21,15 @@ boundaries and invariants.
|
||||
| Adding, changing, reviewing, or deleting tests | [Testing policy](policy/testing.md) and focused package tests | The policy defines risk-based sufficiency, durable test boundaries, doubles, and test-maintenance criteria. |
|
||||
| CLI commands, flags, output, quiet mode, or command wiring | [CLI reference](cli.md) and [CLI internals](internal/cli.md) | The reference owns the user contract; the internal guide owns command composition and output flow. |
|
||||
| Configuration fields, defaults, loading, overrides, validation, or secrets | [Configuration reference](config.md), [architecture policy](policy/architecture.md), and tests under `internal/config` | These separate the user-visible contract, architectural rules, and executable behavior. |
|
||||
| Top-level generation, batch, collection, inspection, or notification workflow | [App orchestration internals](internal/app-orchestration.md) | It owns workflow ordering, persistence points, failure propagation, and orchestration invariants. |
|
||||
| Top-level generation, batch, collection, output publication, or notification workflow | [App orchestration internals](internal/app-orchestration.md) | It owns workflow ordering, output publication, failure propagation, and orchestration invariants. |
|
||||
| Weather API transport, source envelopes, source warnings, or collection | [Weather API integration](integrations/weatherapi.md), [weather-data internals](internal/weather-data.md), and [collection internals](internal/collect.md) | These separate the external contract, normalized source facts, and app-facing collection behavior. |
|
||||
| Forecast periods, weather derivation, collected facts, or derived facts | [Forecast derivation internals](internal/forecast-derivation.md) and [fact contracts](internal/facts.md) | They own deterministic derivation and the fact boundaries used by reports. |
|
||||
| Report definitions, valid periods, report IDs, output naming, or batch composition | [Report registry internals](internal/report-registry.md) and [app orchestration internals](internal/app-orchestration.md) | Report definitions own selection and period rules; orchestration owns execution. |
|
||||
| Module IDs, module composition, briefing values, or prompt-facing exports | [Module contract internals](internal/module.md), [module builder internals](internal/briefing.md), and [prompt-input internals](internal/prompt-input.md) | These own module contracts, value construction, and the curated prompt-package boundary. |
|
||||
| Recent Changes comparison | [Changes internals](internal/changes.md) and [operations guide](operations.md) | The internal guide owns structured comparison; operations owns user-visible artifact behavior. |
|
||||
| Prompt execution, profiles, prompt inputs, or result handling | `internal/promptexec`, the Promptkit adapter, and [prompt-input internals](internal/prompt-input.md) | These separate the executor contract and input construction. |
|
||||
| Generated-text schemas, validation, render contexts, templates, or Markdown rendering | [Generated-text internals](internal/generatedtext.md), [report-template internals](internal/reporttemplate.md), and [report template guide](templates.md) | These own structured text, renderer implementation, and the maintainer-facing template surface. |
|
||||
| Workspace paths, metadata, atomic persistence, lookup, inspection, diagnosis, or recovery | [State internals](internal/state.md) and [operations guide](operations.md) | These separate implementation behavior from operator workflows, diagnosis, and recovery. |
|
||||
| Distributor bundles, uploads, notification artifacts, or failures | [Distributor adapter internals](internal/distributor-adapter.md), [Distributor integration contracts](integrations/distributor/), and [operations guide](operations.md) | These separate adapter behavior, external contracts, and operational lifecycle. |
|
||||
| Output destinations, atomic publication, prompt diagnosis, or legacy cleanup | [Operations guide](operations.md) and [App orchestration internals](internal/app-orchestration.md) | Operations owns operator workflows; app internals owns the implementation boundary. |
|
||||
| Distributor bundles, uploads, notification results, or failures | [Distributor adapter internals](internal/distributor-adapter.md), [Distributor integration contracts](integrations/distributor/), and [operations guide](operations.md) | These separate adapter behavior, external contracts, and operational lifecycle. |
|
||||
| Maintained example configuration | [Configuration reference](config.md) and files under `examples/` | The reference owns field meaning; examples own complete copyable files. |
|
||||
| Release preparation, tagging, publication, or verification | [Release procedure](release.md) | It owns version selection, release-note preparation, candidate validation, tag publication, CI behavior, and post-publication checks. |
|
||||
| Proposed, deferred, or unimplemented work | Documents under `docs/roadmap/` | Future behavior and implementation status belong only in roadmaps until implemented. |
|
||||
@@ -45,13 +44,13 @@ present before introducing a new package or abstraction.
|
||||
| --- | --- |
|
||||
| `cmd/weatherreporter` | Binary entry point. |
|
||||
| `internal/cli` | Command parsing, flags, help, output, and command wiring. |
|
||||
| `internal/app` | Generation, batches, collection coordination, notification, and inspection orchestration. |
|
||||
| `internal/app` | Stateless generation, batches, collection coordination, output publication, and notification. |
|
||||
| `internal/config` | Configuration defaults, loading, precedence, secrets, and validation. |
|
||||
| `internal/adapters` | Weather API, Promptkit, and Distributor boundaries. |
|
||||
| `internal/weatherdata`, `internal/forecast`, `internal/facts` | Normalized source facts and deterministic derivation. |
|
||||
| `internal/report`, `internal/module`, `internal/briefing`, `internal/changes` | Report registry, module contracts and values, and structured comparison. |
|
||||
| `internal/promptinput`, `internal/generatedtext`, `internal/reporttemplate` | Prompt packages, generated-text validation, render contexts, and Markdown templates. |
|
||||
| `internal/state`, `internal/fileutil`, `internal/timeutil` | Durable artifacts, atomic file operations, clocks, dates, timezones, and periods. |
|
||||
| `internal/fileutil`, `internal/timeutil` | Atomic output operations, clocks, dates, timezones, and periods. |
|
||||
| `docs` | User, operator, integration, internal, policy, and roadmap documentation. |
|
||||
| `examples` | Maintained copyable configuration. |
|
||||
|
||||
|
||||
@@ -1,30 +1,59 @@
|
||||
# Weatherreporter Operations
|
||||
|
||||
This guide covers normal operation, managed workspace state, inspection,
|
||||
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.
|
||||
This guide covers normal output handling, Distributor notification, secure
|
||||
prompt diagnostics, and cleanup of legacy application state. See the [CLI
|
||||
reference](cli.md) for command syntax and the [configuration reference](config.md)
|
||||
for fields, defaults, and notification templates.
|
||||
|
||||
## Normal Operation
|
||||
|
||||
After configuring a Weather API endpoint, generate one report:
|
||||
|
||||
```sh
|
||||
weatherreporter generate today --out ./today.md
|
||||
weatherreporter generate today
|
||||
```
|
||||
|
||||
A generation collects weather data, resolves the report period, builds and
|
||||
persists the module snapshot and prompt data package, records Promptkit
|
||||
preparation provenance before provider execution, then persists raw output and
|
||||
execution provenance, validates the structured generated text, and renders the
|
||||
managed Markdown report from the validated text and deterministic values.
|
||||
These receipts describe the current workspace implementation; they are not a
|
||||
cross-version profile-provenance contract.
|
||||
The command writes `today.md` in the current directory. Choose a different
|
||||
operator-owned file with `--out`; a relative path is resolved from the current
|
||||
directory and an absolute path is used directly. Weatherreporter renders in
|
||||
memory and atomically replaces the selected destination only after generation
|
||||
and rendering succeed. It does not create a default workspace, metadata,
|
||||
receipts, or intermediate output files.
|
||||
|
||||
The managed report and its final metadata are saved before single-report
|
||||
Distributor notification is attempted. `--out` writes an extra operator copy;
|
||||
it never changes the managed report or upload source. A successful generate
|
||||
command prints its summary to stdout unless `--quiet` is used.
|
||||
Before a destination is published, provider, validation, rendering, write, and
|
||||
cancellation failures leave an existing report unchanged. A notification
|
||||
failure happens after publication, so retain and use the completed Markdown
|
||||
file while resolving the delivery error. The JSON result identifies the
|
||||
absolute output path and active profile, backend, model, warnings, validation,
|
||||
debug, and notification information; see the [CLI reference](cli.md) for its
|
||||
exact fields.
|
||||
|
||||
## Batch Outputs And Distributor Notification
|
||||
|
||||
Run a scheduled batch with an explicit output directory when appropriate:
|
||||
|
||||
```sh
|
||||
weatherreporter run morning --out-dir ./reports
|
||||
```
|
||||
|
||||
Without `--out-dir`, batch reports are written beneath the current directory.
|
||||
Morning runs Today, Tomorrow, and every eligible dated Daily Report; evening
|
||||
runs Tomorrow and the same eligible Daily Reports. Eligible Daily dates begin
|
||||
after tomorrow and require complete hourly coverage for their local civil day.
|
||||
A batch collects once, processes each selected report independently, and keeps
|
||||
successful outputs if another report fails.
|
||||
|
||||
When `notify.distributor.enabled` and batch notification are enabled,
|
||||
Weatherreporter sends one Distributor upload only after every selected output
|
||||
exists. If an item fails, the batch notification is skipped and successful
|
||||
files remain at their selected destinations. A batch notification failure also
|
||||
leaves all successfully published report files in place. Distributor source
|
||||
files are those operator-owned Markdown outputs; rendered bundle paths and
|
||||
delivery status appear in the result, not in a local notification receipt.
|
||||
|
||||
For a single report, Distributor notification follows the atomic output write.
|
||||
See the [configuration reference](config.md) for pipeline, bundle,
|
||||
idempotency-key, and per-report path templates.
|
||||
|
||||
## Local Prompt Profile Override
|
||||
|
||||
@@ -36,20 +65,11 @@ set its `endpoint` and `model` for the local server, and configure the copy as
|
||||
completely replaces the embedded definition; it does not affect a report that
|
||||
selects another profile ID.
|
||||
|
||||
For example, install the profile file at a known absolute path and set:
|
||||
|
||||
```yaml
|
||||
promptkit:
|
||||
profile_file: /etc/weatherreporter/weather-light-local-profile.yml
|
||||
```
|
||||
|
||||
Prompt inspection occurs before weather collection. A malformed profile file,
|
||||
missing required credential, or unsupported selected backend stops the command
|
||||
before collection. A reachable profile can still fail later if its local model
|
||||
endpoint is unavailable; Weatherreporter does not switch to a remote profile.
|
||||
See the [configuration reference](config.md) for field definitions. For a
|
||||
provider failure, start with the command error and enable secure prompt debug
|
||||
capture when content-rich diagnostics are required.
|
||||
Prompt and profile validation occurs before weather collection. A malformed
|
||||
profile file, missing required credential, or unsupported selected backend
|
||||
stops the command before collection. A reachable profile can still fail later
|
||||
if its local model endpoint is unavailable; Weatherreporter does not switch to
|
||||
a remote profile.
|
||||
|
||||
## Optional Prompt Debug Capture
|
||||
|
||||
@@ -59,153 +79,41 @@ Use `--llm-debug-dir` only when content-rich prompt diagnostics are required:
|
||||
weatherreporter generate today --llm-debug-dir /var/tmp/weatherreporter-debug
|
||||
```
|
||||
|
||||
The directory must be absolute and is initialized before prompt inspection or
|
||||
weather collection. Capture files are stored outside the managed workspace,
|
||||
with restrictive permissions, under the report ID, valid date, and RunID.
|
||||
They can contain rendered prompts and generated output, so the normal metadata,
|
||||
CLI summary, and routine logs contain only the optional directory path—not
|
||||
their content. A capture-write failure stops that run before later work can
|
||||
continue.
|
||||
The directory must be absolute. Requested captures are written with restrictive
|
||||
permissions beneath the supplied directory, organized by report and run. They
|
||||
can contain rendered prompts and generated output, so limit access to trusted
|
||||
operators and remove the captures when they are no longer needed. Normal output,
|
||||
summaries, and routine logs omit that sensitive content. Debug capture is never
|
||||
created for an ordinary command without `--llm-debug-dir`.
|
||||
|
||||
Run a scheduled batch with the same configured collection:
|
||||
If capture creation or writing fails, the affected run fails rather than
|
||||
silently continuing without the requested diagnostics.
|
||||
|
||||
## Diagnosing Failures
|
||||
|
||||
Start with the command error and JSON summary. For a report generation failure,
|
||||
the selected destination was not replaced; for a notification failure, inspect
|
||||
the completed destination and the notification result. For a batch failure,
|
||||
use the per-report statuses and retain successful output files. Enable explicit
|
||||
debug capture only when content-rich Promptkit diagnostics are necessary.
|
||||
|
||||
Weatherreporter does not retain runs for later inspection, resume failed work,
|
||||
or provide automatic cleanup, archival, remote state, daemon operation, or
|
||||
automatic storm monitoring.
|
||||
|
||||
## Manual Cleanup Of Legacy Workspaces
|
||||
|
||||
Older installations may have a directory named `workspace` containing reports,
|
||||
snapshots, prompt inputs, or notification records from previous versions.
|
||||
Current commands neither read nor update it. After confirming that no separate
|
||||
retention requirement applies, remove that specific legacy directory manually;
|
||||
do not use a broad cleanup command that could remove current operator outputs.
|
||||
|
||||
For example, from the directory that contains the old directory:
|
||||
|
||||
```sh
|
||||
weatherreporter run morning --out-dir ./reports --llm-debug-dir /var/tmp/weatherreporter-debug
|
||||
rm -rf ./workspace
|
||||
```
|
||||
|
||||
Each batch validates its configured prompt/profile candidates, then collects once before it plans reports. Morning runs Today, Tomorrow,
|
||||
and every eligible dated Daily Report; evening runs Tomorrow and the same
|
||||
eligible Daily Reports. Eligible Daily dates begin after tomorrow and require
|
||||
complete hourly coverage for their entire local civil day. A batch continues
|
||||
after an individual report fails and returns an aggregate failure when any
|
||||
report or batch notification fails.
|
||||
|
||||
`--out-dir` writes extra copies such as `today.md`, `tomorrow.md`, and
|
||||
`daily-YYYY-MM-DD.md`. These copies are never upload sources. Batch report
|
||||
copies and notification behavior are summarized in the CLI result; use the
|
||||
[CLI reference](cli.md) for its exact JSON and stderr contract.
|
||||
|
||||
## Managed 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
|
||||
workspace/
|
||||
reports/<artifact_group>/<YYYY-MM-DD>/report.<run_id>.md
|
||||
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/modules.<run_id>.json
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/metadata.<run_id>.json
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/generated_text_raw.<run_id>.json
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/prompt_execution.<run_id>.json
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/generated_text.<run_id>.json
|
||||
snapshots/<artifact_group>/<YYYY-MM-DD>/render_context.<run_id>.json
|
||||
|
||||
data-packages/<artifact_group>/<YYYY-MM-DD>/data_package.<run_id>.yaml
|
||||
preflight/<artifact_group>/<YYYY-MM-DD>/prompt_preparation.<run_id>.json
|
||||
|
||||
notifications/<artifact_group>/<YYYY-MM-DD>/distributor.<run_id>.json
|
||||
notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json
|
||||
```
|
||||
|
||||
The generated-text and render-context artifacts are written for every completed
|
||||
single-report generation.
|
||||
A report's metadata links the module snapshot, data package, preparation and
|
||||
execution receipts, managed report, generated-text artifacts, and any available single-report
|
||||
notification artifact. These current-version receipts are implementation
|
||||
details rather than durable interfaces. Use the active command's error and
|
||||
explicit secure debug capture for prompt diagnosis. Batch
|
||||
notification artifacts are separate batch-level records under
|
||||
`notifications/batches`.
|
||||
|
||||
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
|
||||
different managed paths. Batch notification RunIDs contain the UTC batch start
|
||||
timestamp and batch name.
|
||||
|
||||
## Distributor Notification
|
||||
|
||||
When `notify.distributor.enabled` is enabled, a successful `generate`
|
||||
uploads only the managed Markdown report after final metadata has been saved.
|
||||
The extra copy from `--out` is never uploaded. A notification attempt writes
|
||||
a redacted debug artifact at
|
||||
`notifications/<artifact_group>/<YYYY-MM-DD>/distributor.<run_id>.json`; its
|
||||
path is then recorded in report metadata.
|
||||
|
||||
Batches suppress per-report notification. When both Distributor and its batch
|
||||
notification are enabled, Weatherreporter submits one multi-report upload after
|
||||
every planned report succeeds. If any report fails, it records a top-level
|
||||
`skipped` notification with reason `one or more reports failed` and does not
|
||||
call Distributor. If batch notification is disabled, a batch does not fall back
|
||||
to individual uploads.
|
||||
|
||||
A batch notification attempt writes
|
||||
`notifications/batches/<batch>/<YYYY-MM-DD>/distributor.<batch_run_id>.json`.
|
||||
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.
|
||||
|
||||
## Inspecting Stored Runs
|
||||
|
||||
Inspection is read-only: it neither collects weather data nor invokes
|
||||
Promptkit or Distributor. Start by finding a RunID:
|
||||
|
||||
```sh
|
||||
weatherreporter inspect reports --limit 10
|
||||
weatherreporter inspect metadata RUN_ID
|
||||
```
|
||||
|
||||
| Command | Reads |
|
||||
| --- | --- |
|
||||
| `inspect reports` | Metadata files under the workspace snapshots tree. |
|
||||
| `inspect metadata RUN_ID` | Metadata located by RunID. |
|
||||
| `inspect modules RUN_ID` | The module snapshot path recorded in metadata. |
|
||||
| `inspect data-package RUN_ID` | The data-package path recorded in metadata. |
|
||||
| `inspect prior RUN_ID` | The run metadata, then compatible earlier metadata for its comparison policy. |
|
||||
| `inspect sources RUN_ID` | Source provenance and warnings in the run metadata. |
|
||||
|
||||
A missing snapshots directory produces no listed reports. An unknown or empty
|
||||
RunID is an error; use `inspect reports` to obtain a valid value.
|
||||
|
||||
New runs write `weatherreporter.metadata.v2`, including preparation and
|
||||
execution references once those receipts exist. `inspect metadata` also reads
|
||||
historic V1 records; their legacy preflight and generated-text-result fields
|
||||
remain visible for compatibility, but Weatherreporter does not write them for
|
||||
new runs.
|
||||
|
||||
## Recovery
|
||||
|
||||
Keep the workspace when a run fails: artifacts reached before the failure
|
||||
remain available where they can be safely persisted.
|
||||
|
||||
- A preparation failure can leave its classified receipt and metadata.
|
||||
- A report-generation failure can leave the managed report, module snapshot,
|
||||
data package, and metadata.
|
||||
- A completed prompt validation rejection leaves raw text, an execution receipt,
|
||||
and metadata. Later generated-text failures can also leave validated text and
|
||||
a render-context artifact, depending on where they stopped.
|
||||
- A single-report notification failure preserves the report and final metadata,
|
||||
including its notification artifact when it was written.
|
||||
- A batch notification failure preserves each report's artifacts and adds the
|
||||
top-level batch notification artifact.
|
||||
|
||||
Use the action summary and its error first. For prompt or provider
|
||||
diagnosis, prefer an explicitly enabled secure debug capture; current-version
|
||||
receipt paths may provide supplemental context when available. For a batch
|
||||
failure, inspect the summary first, then inspect the affected report RunIDs or
|
||||
the batch notification path. Do not remove the whole workspace as a first
|
||||
response; retain it until the failure is understood.
|
||||
|
||||
## Operational Caveats
|
||||
|
||||
- Workspace files and generated reports can contain
|
||||
sensitive operational context. Set appropriate filesystem permissions and do
|
||||
not publish them unintentionally.
|
||||
- Weatherreporter uses one configured Weather API endpoint and local workspace
|
||||
state.
|
||||
- Promptkit profile resolution does not discover local endpoints or fail over
|
||||
between local and remote profiles.
|
||||
- It does not provide automatic resume, cleanup, archival, remote state, daemon
|
||||
operation, or automatic storm monitoring.
|
||||
This removal cannot be recovered by Weatherreporter. Keep or archive any
|
||||
historical files that are still needed before deleting them.
|
||||
|
||||
@@ -10,9 +10,10 @@ package inventory; focused documents in `docs/internal/` own implementation deta
|
||||
|
||||
Weatherreporter is a deterministic weather-report CLI. It collects normalized
|
||||
weather data, derives facts and modules, builds a curated YAML data package,
|
||||
compares prior snapshots, executes exact-version Promptkit prompts, validates
|
||||
structured generated prose, and renders repository-owned Markdown. Completed
|
||||
managed Markdown may be uploaded through Distributor.
|
||||
executes exact-version Promptkit prompts, validates structured generated prose,
|
||||
and renders repository-owned Markdown in memory. Completed Markdown is
|
||||
atomically published to an operator-owned output destination and may then be
|
||||
uploaded through Distributor.
|
||||
|
||||
The supported report products are Daily, Today, Tomorrow, and Hourly. A batch
|
||||
collects once, validates its complete candidate prompt/profile set before
|
||||
@@ -25,14 +26,12 @@ after every planned report succeeds.
|
||||
- `internal/cli` owns command parsing, help, summaries, and one executor
|
||||
construction per action.
|
||||
- `internal/config` owns defaults, loading, validation, and secret loading.
|
||||
- `internal/app` owns workflow order, partial results, and notification
|
||||
coordination through project-owned contracts.
|
||||
- `internal/app` owns in-memory workflow order, partial results, atomic output
|
||||
publication, and notification coordination through project-owned contracts.
|
||||
- Deterministic domain packages own weather derivation, report periods, modules,
|
||||
generated-text validation, and template contexts.
|
||||
- `internal/adapters/weatherapi`, `internal/adapters/promptkit`, and
|
||||
`internal/adapters/distributor` own their external dependency mechanics.
|
||||
- `internal/state` owns workspace paths, V2 metadata, atomic persistence, and
|
||||
read-only inspection.
|
||||
|
||||
Dependency-specific Promptkit types remain inside its adapter. The application
|
||||
does not parse flags, construct provider clients, or render provider output
|
||||
@@ -41,28 +40,29 @@ directly.
|
||||
## Prompt Execution Invariants
|
||||
|
||||
- Prompts receive curated module packages, never unbounded raw weather payloads.
|
||||
- Every execution inspects the exact prompt version and output contract before
|
||||
- Every execution validates the exact prompt version and output contract before
|
||||
collection. The selected profile is configured explicitly or declared by the
|
||||
prompt; unsupported direct-key profiles and missing reported credentials fail
|
||||
before collection.
|
||||
- Prepared execution persists safe preparation provenance before provider work.
|
||||
Completed execution persists safe execution provenance; raw output is
|
||||
validated before template rendering.
|
||||
- Prompt and profile validation completes before weather collection. Raw output
|
||||
is validated before template rendering.
|
||||
- Generated text fills defined prose slots only. Deterministic facts remain
|
||||
authoritative and repository-owned templates produce all managed Markdown.
|
||||
- Sensitive rendered prompts, schemas, input bodies, provider endpoints, and
|
||||
credentials never enter normal metadata, summaries, logs, or workspace
|
||||
artifacts. They are written only to an explicit secure debug root when
|
||||
requested.
|
||||
credentials never enter normal summaries or logs. They are written only to
|
||||
an explicit secure debug root when requested.
|
||||
|
||||
## State, Notification, And Testing Invariants
|
||||
## Output, Notification, And Testing Invariants
|
||||
|
||||
- Managed writes are atomic where practical and stay beneath the configured
|
||||
workspace root. Reached artifacts remain inspectable after later failures.
|
||||
- New records use `weatherreporter.metadata.v2`; V1 records remain readable for
|
||||
inspection compatibility.
|
||||
- Distributor uploads use only the managed Markdown report, never output copies
|
||||
or workspace scans. Notification follows report and final metadata success.
|
||||
- Normal execution is stateless: it keeps weather data, prompt input, generated
|
||||
text, and render context in memory and creates no application-owned durable
|
||||
state.
|
||||
- Markdown writes are atomic at an operator-selected destination. A
|
||||
pre-publication failure does not replace an existing destination; a
|
||||
notification failure does not remove a newly published output.
|
||||
- Distributor uploads use only the published Markdown output, never a scan of
|
||||
local files. Single notification follows publication; batch notification
|
||||
follows publication of every selected report.
|
||||
- Default tests are deterministic, offline, and use Promptkit/provider fakes
|
||||
rather than live provider calls. See the [testing policy](testing.md).
|
||||
|
||||
|
||||
@@ -85,8 +85,8 @@ mechanisms, not secret values.
|
||||
| Release procedure | `docs/release.md` | Version policy, release preparation, validation, tagging, automated publication, verification, failure handling, and release ordering. | General contributor workflow, product contracts, release-specific change summaries, and implementation history. |
|
||||
| Release notes | `docs/releases/` | One versioned, changelog-style summary for each release, including compatibility and operator action. The file at the tagged commit supplies the corresponding Gitea release body. | Current CLI, configuration, operations, integration, architecture, and internal contracts; release procedure; implementation plans. |
|
||||
| CLI contract | `docs/cli.md` | Commands, arguments, flags, invocation semantics, stdout and stderr behavior, summaries, and exit behavior. | Configuration field definitions, complete operating procedures, runtime filesystem layout, and command implementation. |
|
||||
| Configuration contract | `docs/config.md` | Discovery and precedence, fields, defaults, secrets, validation rules, and user-selectable values. | Complete example files, CLI syntax, runtime state lifecycle, and loading implementation. |
|
||||
| Operations | `docs/operations.md` | Normal workflows, physical workspace layout, artifacts and metadata, inspection, notification behavior, diagnosis, recovery, cleanup, permissions, and operational caveats. | Complete CLI syntax, configuration field definitions, logical external contracts, and implementation mechanics. |
|
||||
| Configuration contract | `docs/config.md` | Discovery and precedence, fields, defaults, secrets, validation rules, and user-selectable values. | Complete example files, CLI syntax, output lifecycle, and loading implementation. |
|
||||
| Operations | `docs/operations.md` | Normal output handling, atomic replacement, notification behavior, diagnosis, explicit debug capture, manual legacy-workspace cleanup, permissions, and operational caveats. | Complete CLI syntax, configuration field definitions, logical external contracts, and implementation mechanics. |
|
||||
| Report template surface | `docs/templates.md` | Implemented template files and partials, render-context fields, editing rules, and maintainer-facing template examples. | Weather derivation, module implementation, generated-text validation internals, and operator procedures. |
|
||||
| External and durable integration contracts | `docs/integrations/` | Weather API, Promptkit, Distributor, external formats and protocols, durable logical paths and schemas, compatibility behavior, and upstream or downstream responsibilities. | Physical runtime placement and lifecycle, internal transformations, CLI syntax, and configuration defaults. |
|
||||
| Internal subsystem behavior | `docs/internal/` | Implementation flow, internal collaborators and state transitions, package-local guarantees and failures, and relevant tests. | Global architecture invariants, user-facing contracts, external schemas, operator procedures, and future package plans. |
|
||||
@@ -113,8 +113,8 @@ parallel package or behavior references.
|
||||
|
||||
CLI documentation answers how to invoke Weatherreporter and what its command
|
||||
interface does. Configuration documentation answers what settings mean.
|
||||
Operations answers what happens to runtime state and how to operate or recover
|
||||
the application, including diagnosis and safe responses to runtime failures.
|
||||
Operations answers how to handle operator-owned outputs and runtime failures,
|
||||
including diagnosis, explicit debug capture, and safe legacy cleanup.
|
||||
|
||||
When a workflow crosses these topics, place the complete procedure with the
|
||||
document that owns the task and link to the other contracts. Do not duplicate
|
||||
|
||||
@@ -96,8 +96,8 @@ Use each test type where it protects a distinct risk:
|
||||
- Integration tests use real deterministic collaborators when correctness
|
||||
depends on their interaction, while replacing live or nondeterministic
|
||||
external boundaries.
|
||||
- App and CLI tests protect representative assembled generation, batch,
|
||||
inspection, persistence, and notification workflows.
|
||||
- App and CLI tests protect representative assembled generation, batch, atomic
|
||||
output, and notification workflows.
|
||||
- Fixtures must be minimal, synthetic, versioned with the behavior they
|
||||
exercise, and free of credentials or private data.
|
||||
- Golden files are appropriate only when the complete output is intentionally
|
||||
@@ -199,9 +199,9 @@ Each behavior should have a clear test owner:
|
||||
- Config tests own loading, precedence, defaults, secrets, and validation.
|
||||
- Domain tests own weather transformations and invariants.
|
||||
- Adapter tests own HTTP, Promptkit/provider, and upload boundaries.
|
||||
- Orchestrator tests own workflow ordering, persistence, partial success, and
|
||||
failure propagation.
|
||||
- State tests own path derivation, atomic artifacts, lookup, and round trips.
|
||||
- Orchestrator tests own workflow ordering, output publication, partial success,
|
||||
and failure propagation.
|
||||
- Filesystem tests own atomic writes and destination-preservation behavior.
|
||||
- Template and generated-text tests own schemas, render contexts, and rendered
|
||||
output contracts.
|
||||
|
||||
@@ -219,8 +219,8 @@ observation:
|
||||
3. Use stubs when a dependency only needs controlled responses.
|
||||
4. Use mocks when the interaction itself is contractual.
|
||||
|
||||
Mocks are appropriate for requirements such as uploading exactly once, saving
|
||||
metadata before notification, propagating cancellation to Promptkit, or
|
||||
Mocks are appropriate for requirements such as uploading exactly once,
|
||||
notifying only after output publication, propagating cancellation to Promptkit, or
|
||||
avoiding an external call after an earlier workflow failure. Do not use mocks
|
||||
merely to isolate every object or reproduce the implementation's call graph.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user