243 lines
8.4 KiB
Markdown
243 lines
8.4 KiB
Markdown
# Roadmap: CLI Output Policy
|
|
|
|
## Purpose
|
|
|
|
Define a shared CLI output policy before adding machine-readable JSON output to
|
|
`distributor` commands.
|
|
|
|
Current CLI output is human-readable text. That is appropriate as the default,
|
|
but upcoming features need a common machine-readable contract so each command
|
|
does not invent a separate JSON flag, envelope, warning policy, or error shape.
|
|
|
|
## Current Implementation Grounding
|
|
|
|
The current CLI has these output-producing commands:
|
|
|
|
- `version`;
|
|
- `run`;
|
|
- `validate`;
|
|
- `inspect`.
|
|
|
|
Current output is text-only. `run` has the most complex output because it can
|
|
print warnings, pipeline summaries, planned destination actions, partial
|
|
destination failures, and a final status line. `validate` and `inspect` are
|
|
currently local-path commands. `version` prints a single text line.
|
|
|
|
Planned `distributor manifest create`, remote `validate` and `inspect`, link
|
|
generation, and latest path destinations increase the need for structured
|
|
output that scripts can consume consistently.
|
|
|
|
## Goals
|
|
|
|
- Define one CLI-wide policy for text and JSON output.
|
|
- Preserve current human-readable text output as the default.
|
|
- Add JSON output consistently across output-producing commands when this
|
|
roadmap is implemented.
|
|
- Keep warning, error, and partial-failure behavior predictable.
|
|
- Avoid external dependencies; use Go's standard `encoding/json`.
|
|
|
|
## Non-Goals
|
|
|
|
- Do not add YAML, table, NDJSON, streaming JSON, or template output formats.
|
|
- Do not change source manifest, destination state, config, or backend schemas.
|
|
- Do not make help or usage output JSON.
|
|
- Do not turn ordinary fatal setup errors into structured JSON results.
|
|
- Do not add a root-global output flag in the first implementation.
|
|
|
|
## Shared CLI Policy
|
|
|
|
Each supported command should accept:
|
|
|
|
```sh
|
|
--format text
|
|
--format json
|
|
```
|
|
|
|
Policy:
|
|
|
|
- `text` is the default and preserves existing output unless a feature
|
|
explicitly changes text output.
|
|
- `json` writes exactly one JSON document to stdout.
|
|
- help and usage output remain text-only.
|
|
- invalid `--format` values are usage errors.
|
|
- `--format` is a per-command flag, not a root-global flag.
|
|
- a command must not accept `--format json` unless it emits the shared JSON
|
|
envelope for that command.
|
|
|
|
The first implementation should add JSON support for all current
|
|
output-producing commands rather than leaving a mixed CLI where some commands
|
|
support `--format` and others do not.
|
|
|
|
## Stdout, Stderr, Warnings, and Errors
|
|
|
|
Text mode keeps the current behavior:
|
|
|
|
- normal command output goes to stdout;
|
|
- warnings may be printed as text;
|
|
- command errors are printed to stderr by CLI error handling.
|
|
|
|
JSON mode:
|
|
|
|
- successful commands write one JSON document to stdout;
|
|
- warnings are included in a top-level `warnings` array and are not duplicated
|
|
to stderr;
|
|
- fatal setup errors that prevent construction of a result write text errors to
|
|
stderr, write no JSON stdout, and exit non-zero;
|
|
- commands with meaningful partial results may write a JSON document with
|
|
`ok: false`, structured failure details, and a non-zero exit status.
|
|
|
|
`run --format json` should use the partial-result behavior when planning or
|
|
execution has begun and one or more destinations fail. This lets automation
|
|
inspect successful actions, failed actions, warnings, and final counters even
|
|
when the process exits non-zero.
|
|
|
|
## JSON Envelope
|
|
|
|
All JSON-mode commands should use a common top-level envelope:
|
|
|
|
```json
|
|
{
|
|
"schema_version": 1,
|
|
"command": "inspect",
|
|
"ok": true,
|
|
"warnings": [],
|
|
"result": {}
|
|
}
|
|
```
|
|
|
|
Envelope fields:
|
|
|
|
- `schema_version`: integer version of the CLI JSON output schema.
|
|
- `command`: command name, using the public CLI command path where useful, such
|
|
as `manifest create`.
|
|
- `ok`: boolean success indicator for the command result.
|
|
- `warnings`: array of structured warning objects.
|
|
- `result`: command-specific result object.
|
|
- `errors`: optional array of structured error objects for commands that can
|
|
return partial results.
|
|
|
|
Field rules:
|
|
|
|
- use stable snake_case field names;
|
|
- use RFC3339 timestamps;
|
|
- use numeric JSON values for sizes and counts;
|
|
- use slash-separated logical paths for bundle, source, destination, and output
|
|
paths;
|
|
- never include secret values;
|
|
- keep command-specific data under `result`;
|
|
- add fields compatibly where practical.
|
|
|
|
Warning objects should include at least:
|
|
|
|
```json
|
|
{
|
|
"message": "secret OBJECT_STORAGE_KEY ignored because the real environment already has that variable"
|
|
}
|
|
```
|
|
|
|
Error objects for partial results should include enough context for automation
|
|
and troubleshooting, such as pipeline id, destination id, backend, bundle path,
|
|
and message when those values are available.
|
|
|
|
## Command Adoption
|
|
|
|
`version`:
|
|
|
|
- text mode keeps the current version string;
|
|
- JSON mode reports application name and version under `result`.
|
|
|
|
`validate`:
|
|
|
|
- text mode keeps the current validation summary;
|
|
- JSON mode reports bundle count and selected bundle identifiers;
|
|
- future remote validation uses the same envelope and adds pipeline/source
|
|
context under `result`.
|
|
|
|
`inspect`:
|
|
|
|
- text mode keeps human-readable bundle metadata;
|
|
- JSON mode reports normalized bundle metadata, including source-relative path,
|
|
bundle id, created timestamp, digest, file count, total size, and file
|
|
records.
|
|
|
|
`run`:
|
|
|
|
- text mode keeps the current progress and final status style unless a future
|
|
feature intentionally changes it;
|
|
- JSON mode reports warnings, pipeline summaries, destination action records,
|
|
output records, final counters, dry-run status, and partial failure records;
|
|
- JSON mode may write `ok: false` with partial results and still exit non-zero.
|
|
|
|
Future `manifest create`:
|
|
|
|
- should use `--format text|json`;
|
|
- text mode should keep concise human success output;
|
|
- JSON mode should report the generated manifest summary under `result`;
|
|
- the command should not introduce a separate `--json` flag.
|
|
|
|
## Relationship To Other Roadmaps
|
|
|
|
`distributor manifest create` should depend on this roadmap for JSON summary
|
|
output and should not add a command-specific JSON flag.
|
|
|
|
Remote `validate` and `inspect` should use this policy for machine-readable
|
|
source validation and inspection.
|
|
|
|
Link generation should expose primary links through JSON command output only
|
|
after this policy is implemented or selected for implementation.
|
|
|
|
Latest path destinations should report fixed-path selection and destructive
|
|
replacement summaries through the same `run --format json` result model.
|
|
|
|
## Testing Expectations
|
|
|
|
Suggested coverage:
|
|
|
|
- CLI parsing accepts `--format text` and `--format json` for supported
|
|
commands;
|
|
- CLI parsing rejects invalid `--format` values as usage errors;
|
|
- help and usage output remain text-only;
|
|
- each JSON-capable command emits exactly one valid JSON document to stdout on
|
|
success;
|
|
- text mode preserves existing output;
|
|
- JSON-mode warnings appear in `warnings` and are not duplicated to stderr;
|
|
- fatal setup errors write no JSON stdout and return non-zero;
|
|
- `run --format json` emits partial-result JSON with `ok: false` and exits
|
|
non-zero when one or more destination failures occur after planning begins;
|
|
- JSON output uses RFC3339 timestamps, numeric sizes and counts, and
|
|
slash-separated logical paths;
|
|
- no JSON output includes secret values;
|
|
- documentation consistency checks find no unsupported `--json` references.
|
|
|
|
## Documentation Updates After Implementation
|
|
|
|
- Update `docs/cli.md` with the shared `--format text|json` policy.
|
|
- Update command examples only for implemented JSON behavior.
|
|
- Update `docs/operations.md` where JSON output materially improves automation
|
|
workflows.
|
|
- Update `docs/troubleshooting.md` only for implemented JSON-mode recovery
|
|
behavior.
|
|
- Update relevant roadmap files when JSON output is no longer deferred.
|
|
|
|
Keep this roadmap under `docs/roadmap/` until implemented.
|
|
|
|
## Decisions
|
|
|
|
- Use per-command `--format text|json`; do not introduce `--json`.
|
|
- Keep `text` as the default for backward compatibility.
|
|
- Implement JSON support for all current output-producing commands when this
|
|
roadmap is selected.
|
|
- Keep help and usage output text-only.
|
|
- Put JSON-mode warnings in the top-level `warnings` array.
|
|
- Allow `run --format json` to emit partial-result JSON with `ok: false` and a
|
|
non-zero exit status.
|
|
- Keep fatal setup errors as text stderr with no JSON stdout.
|
|
|
|
## Future Work
|
|
|
|
- Consider a root-global output flag only if the command parser is later
|
|
refactored around shared root options.
|
|
- Consider additional formats only if a concrete consumer requires them.
|
|
- Consider a versioned JSON schema reference after the first JSON-capable
|
|
release.
|