Update default sections of the Area Forecast Discussion provided to different report types
This commit is contained in:
@@ -1,241 +0,0 @@
|
||||
# CLI Output Roadmap
|
||||
|
||||
## Purpose
|
||||
|
||||
This roadmap defines the intended final shape for weatherreporter CLI output.
|
||||
|
||||
The current CLI has drifted:
|
||||
|
||||
- `run` commands emit JSON summaries to stdout and compact status lines to
|
||||
stderr.
|
||||
- `inspect` commands emit JSON to stdout.
|
||||
- `generate` commands perform substantial work but are silent on success.
|
||||
|
||||
The target is a predictable command-line contract that is useful for operators,
|
||||
easy to consume from scripts, and explicit enough that future commands naturally
|
||||
reuse the same output path.
|
||||
|
||||
## Locked Decisions
|
||||
|
||||
- Keep application orchestration and domain decisions in `internal/app`.
|
||||
- Keep CLI presentation, stdout/stderr policy, and quiet-mode behavior in
|
||||
`internal/cli`.
|
||||
- Successful non-help commands should have a machine-readable JSON stdout
|
||||
contract unless `--quiet` intentionally suppresses success output for an
|
||||
action command.
|
||||
- Help remains human-readable text.
|
||||
- Stderr is for compact operational status and errors, not primary command
|
||||
payloads.
|
||||
- Do not print partial JSON when command construction, flag parsing, config
|
||||
loading, or pre-run validation fails.
|
||||
- Do not serialize large internal app objects directly as CLI output.
|
||||
- Do not expose secret values in stdout or stderr.
|
||||
- Add `--quiet` for state-changing action commands.
|
||||
- Do not make `--quiet` suppress requested inspection data.
|
||||
|
||||
## Command Categories
|
||||
|
||||
CLI commands should be classified into one of these output categories.
|
||||
|
||||
### Help Commands
|
||||
|
||||
Examples:
|
||||
|
||||
- `weatherreporter --help`
|
||||
|
||||
Output:
|
||||
|
||||
- stdout: human-readable help text
|
||||
- stderr: none on success
|
||||
- `--quiet`: not applicable
|
||||
|
||||
### Action Commands
|
||||
|
||||
Examples:
|
||||
|
||||
- `weatherreporter generate today`
|
||||
- `weatherreporter generate daily --date YYYY-MM-DD`
|
||||
- `weatherreporter run morning`
|
||||
- `weatherreporter run evening`
|
||||
|
||||
Output:
|
||||
|
||||
- stdout: compact JSON summary after the action completes
|
||||
- stderr: compact status lines only when useful, especially for multi-report
|
||||
batch commands
|
||||
- `--quiet`: suppress success stdout and routine status stderr
|
||||
|
||||
Failure behavior:
|
||||
|
||||
- For flag/config/pre-run errors, stdout is empty and the command returns an
|
||||
error.
|
||||
- For completed actions that produce an inspectable failure result, default
|
||||
output may still include a JSON failure summary before returning nonzero.
|
||||
- With `--quiet`, failure diagnostics should remain concise and actionable on
|
||||
stderr through the existing top-level error path; routine success summaries
|
||||
stay suppressed.
|
||||
|
||||
### Inspection Commands
|
||||
|
||||
Examples:
|
||||
|
||||
- `weatherreporter inspect reports`
|
||||
- `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`
|
||||
|
||||
Output:
|
||||
|
||||
- stdout: requested JSON data
|
||||
- stderr: none on success
|
||||
- `--quiet`: not accepted unless a future inspection command has auxiliary
|
||||
status output to suppress
|
||||
|
||||
Inspection commands are already data-oriented. Their stdout payload should stay
|
||||
focused on the requested data rather than being hidden by quiet mode.
|
||||
|
||||
## Target Action Summary Shape
|
||||
|
||||
Action command JSON should be small, stable, and path-oriented. It should expose
|
||||
what an operator needs to find artifacts, inspect a run, and understand
|
||||
notification status.
|
||||
|
||||
### Generate Summary
|
||||
|
||||
Target shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "generate",
|
||||
"reportId": "today",
|
||||
"reportName": "Today Report",
|
||||
"promptId": "weather.today_generated_text",
|
||||
"runId": "20260529T100000.000000000Z_today",
|
||||
"status": "succeeded",
|
||||
"generatedAt": "2026-05-29T10:00:00Z",
|
||||
"validPeriod": {},
|
||||
"reportPath": "workspace/reports/today/2026-05-29/report.20260529T100000.000000000Z_today.md",
|
||||
"outputPath": "./today.md",
|
||||
"metadataPath": "workspace/snapshots/today/2026-05-29/metadata.20260529T100000.000000000Z_today.json",
|
||||
"dataPackagePath": "workspace/data-packages/today/2026-05-29/data_package.20260529T100000.000000000Z_today.yaml",
|
||||
"preflightPath": "workspace/preflight/today/2026-05-29/render.20260529T100000.000000000Z_today.json",
|
||||
"notificationPath": "workspace/notifications/today/2026-05-29/distributor.20260529T100000.000000000Z_today.json",
|
||||
"notification": {
|
||||
"status": "succeeded",
|
||||
"runId": "distributor-run",
|
||||
"pipelineId": "weatherreporter.today",
|
||||
"bundleId": "weatherreporter.home.today",
|
||||
"path": "workspace/notifications/today/2026-05-29/distributor.20260529T100000.000000000Z_today.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Omit absent optional paths with `omitempty`.
|
||||
- Include generated-text artifact paths only for report modes that produce them.
|
||||
- Include notification fields only when notification was attempted.
|
||||
- Keep module snapshot contents, data package contents, raw generated text,
|
||||
render result bodies, and full notification adapter payloads out of the CLI
|
||||
summary.
|
||||
|
||||
### Batch Summary
|
||||
|
||||
The current `BatchResult` shape is close to the target and should remain the
|
||||
basis for `run` output. The target update is to make the summary explicitly
|
||||
command-like and align status semantics with generate output:
|
||||
|
||||
```json
|
||||
{
|
||||
"command": "run",
|
||||
"batch": "morning",
|
||||
"status": "succeeded",
|
||||
"startedAt": "2026-05-29T10:00:00Z",
|
||||
"finishedAt": "2026-05-29T10:01:00Z",
|
||||
"total": 3,
|
||||
"succeeded": 3,
|
||||
"failed": 0,
|
||||
"notification": {},
|
||||
"reports": []
|
||||
}
|
||||
```
|
||||
|
||||
Rules:
|
||||
|
||||
- Keep per-report items compact and path-oriented.
|
||||
- Keep batch notification status at the top level.
|
||||
- Preserve nonzero exit behavior when one or more reports fail.
|
||||
- Preserve the existing behavior that batch report failures do not prevent the
|
||||
JSON summary from being available in default output mode.
|
||||
|
||||
## Quiet Mode
|
||||
|
||||
`--quiet` should be available on action commands:
|
||||
|
||||
```sh
|
||||
weatherreporter generate today --quiet
|
||||
weatherreporter run morning --quiet
|
||||
```
|
||||
|
||||
Quiet mode means:
|
||||
|
||||
- no stdout on successful action commands
|
||||
- no routine status lines on stderr on successful action commands
|
||||
- errors still return nonzero and are still reported by the top-level CLI error
|
||||
path
|
||||
- inspection output is not suppressed
|
||||
|
||||
Quiet mode does not mean:
|
||||
|
||||
- skipping artifact writes
|
||||
- skipping distributor notification
|
||||
- changing JSON shape when JSON is emitted
|
||||
- hiding errors
|
||||
|
||||
Future action commands should opt into quiet mode by using the centralized
|
||||
action-output writer rather than implementing their own flag or writer logic.
|
||||
|
||||
## Intended Code Structure
|
||||
|
||||
`internal/cli` should own a small output layer that future commands can reuse.
|
||||
The output layer should make the consistent path the easiest path.
|
||||
|
||||
Target files:
|
||||
|
||||
- `internal/cli/root.go`: command routing and flag parsing
|
||||
- `internal/cli/output.go`: stdout/stderr writers, quiet-mode handling, and
|
||||
output category helpers
|
||||
- `internal/cli/result.go`: CLI-safe summary structs and conversion helpers
|
||||
|
||||
Target app-layer shape:
|
||||
|
||||
- Add a detailed generate entry point that returns the generated report result.
|
||||
- Keep `app.Generate(ctx, GenerateRequest) error` as a convenience wrapper for
|
||||
callers that do not need CLI output.
|
||||
- Keep `app.RunBatchDetailed(ctx, BatchRequest) (*BatchResult, error)` as the
|
||||
batch command result source.
|
||||
|
||||
Target CLI output helpers:
|
||||
|
||||
- `writeJSON(io.Writer, any) error`
|
||||
- `writeActionResult(stdout, stderr io.Writer, result actionResult, opts outputOptions) error`
|
||||
- `writeBatchStatus(stderr io.Writer, result *app.BatchResult)`
|
||||
- `writeGenerateStatus(stderr io.Writer, result GenerateSummary)` only if
|
||||
single-report status lines become useful
|
||||
|
||||
The command router should not call `json.NewEncoder` directly outside the
|
||||
central output helpers.
|
||||
|
||||
## Deferred Questions
|
||||
|
||||
None of these are required for the initial harmonization:
|
||||
|
||||
- global `--format` support
|
||||
- NDJSON progress streams
|
||||
- human-readable success output
|
||||
- machine-readable error envelopes on stderr
|
||||
- making inspection commands use a common envelope
|
||||
|
||||
These should remain deferred until there is a real consumer need.
|
||||
Reference in New Issue
Block a user