Record progress controls and reporting prefixes

This commit is contained in:
2026-10-24 00:42:35 +00:00
parent 2e337155ce
commit 810333e376

View File

@@ -1,13 +1,14 @@
# Output policy and invocation reporting
Status: initial planning. Message categories, all four output modes, uniform
treatment of help and version, and OD-1's flag grammar and scope are selected.
treatment of help and version, message prefixes, and OD-1's flag grammar and
scope (including independent Progress control) are selected.
Consumer API and delivery mechanics remain open. Implementation has not started.
## Purpose
Provide consistent handling of `--quiet`, `--verbose`, and `--debug` across
application commands and optional integrations. Reduce
Provide consistent handling of `--quiet`, `--verbose`, `--debug`, and
`--progress` across application commands and optional integrations. Reduce
repeated output classification, diagnostic presentation, and delivery bookkeeping
where CommandKit can provide a meaningful benefit.
@@ -46,7 +47,9 @@ Distinguish substantive application output from diagnostic message categories:
- **Error:** The invocation failed and will return a non-zero status code.
- **Warning:** Something went wrong or deserves attention, but the invocation
can still succeed. A recovered problem is a warning.
- **Info:** Progress or useful explanation, including completion messages.
- **Info:** Informational context and useful explanation, such as which profile
was selected or a final operation summary.
- **Progress:** Streaming updates about work underway, such as items processed.
- **Debug:** Troubleshooting detail, including intermediate decisions and
execution-path information.
@@ -59,12 +62,18 @@ Debug mode adds troubleshooting detail to verbose output:
| Warning | Suppressed | Suppressed | Shown | Shown |
| Info | Suppressed | Suppressed | Shown | Shown |
| Debug | Suppressed | Suppressed | Suppressed | Shown |
| Progress, without an explicit setting | Suppressed | Suppressed | Suppressed | Shown |
Info belongs in verbose mode; debug includes verbose messages. Normal output
remains a substantive result category, separate from diagnostic severity.
The category of a message determines its visibility; stream destination alone
cannot distinguish a warning from an error.
Progress is distinct from Info and is controlled separately as specified below.
Applications and integrations are not required to generate messages in any
category. Enabling a category adds no output when there are no messages in it;
other output remains subject to its own visibility rules.
Error presentation is tied to invocation failure. Prefer deriving error
diagnostics from a failed outcome, which may carry detailed explanations. Avoid
an unrestricted `Error(...)` reporting method that permits an error message
@@ -84,6 +93,18 @@ Usage and operational failures still report their errors in quiet mode.
The feature must distinguish successful output suppression from failure
diagnostic delivery.
### Message prefixes and channels
Use `WARN:`, `DEBUG:`, and `ERROR:` prefixes for simple warning, debug, and error
messages respectively. Substantive output and Info messages have no prefix.
For multiline diagnostics, prefix the opening line and preserve the structured
detail. Integration adapters coordinate native diagnostic rendering to avoid
duplicate severity labels or loss of upstream formatting.
Streaming Progress messages use the diagnostic channel so they do not corrupt
substantive output such as JSON or YAML. Progress presentation details remain
part of the consumer API and delivery design below.
## Selected flag grammar and scope
### Mode selection and resets
@@ -115,10 +136,43 @@ requested operation and returns the ordinary outcome. Apply the policy through
CommandKit-managed reporting and streams. Output written directly to process
streams or external destinations remains application-owned.
### Progress selection
`--progress` enables Progress without enabling Info, Warning, or Debug messages.
`--progress=false` explicitly disables it. Accept the existing boolean syntax;
repeated canonical or aliased progress settings use the last value. Retain
whether a setting was explicitly supplied, separately from its boolean value.
Determine effective Progress visibility from the final presentation mode and
explicit progress setting:
1. Quiet mode always suppresses Progress.
2. Otherwise, an explicit progress setting controls visibility.
3. Without an explicit setting, debug enables Progress; ordinary and verbose
modes leave it disabled.
An explicit progress setting overrides the mode's default regardless of its
position relative to mode flags. It does not select or reset the presentation
mode. Debug includes verbose detail and defaults Progress on; verbose alone
does not enable Progress.
| Flags | Result |
| --- | --- |
| `--verbose` | Warning and Info, without Progress. |
| `--verbose --progress` | Warning, Info, and Progress. |
| `--debug` | Warning, Info, Debug, and Progress. |
| `--debug --progress=false` or `--progress=false --debug` | Debug detail without Progress. |
| `--quiet --progress` or `--progress --quiet` | Only failure diagnostics. |
| `--debug --verbose` | Verbose detail without Progress, absent an explicit progress setting. |
Passing `--progress` to an application that emits no Progress messages adds no
visible output. It does not suppress that application's substantive results or
require a progress implementation.
### Placement, availability, and aliases
Core supplies `--quiet`, `--verbose`, and `--debug` for application commands,
integrations, the root, canonical groups, and alias-only discovery help.
Core supplies `--quiet`, `--verbose`, `--debug`, and `--progress` for application
commands, integrations, the root, canonical groups, and alias-only discovery help.
Consumers do not register them individually. Preserve the existing placement
grammar: flags follow the complete command path and may be interspersed with
operands after that path. For example:
@@ -134,7 +188,7 @@ Options before or between command-path components are outside this grammar.
Tokens consumed as values and tokens following `--` retain their ordinary
meaning.
Reserve the three long spellings. Applications may add `-q`, `-v`, or `-d`
Reserve the four long spellings. Applications may add `-q`, `-v`, or `-d`
through the alias API; no built-in short spellings are selected. An application
flag declaration that defines a reserved long name fails installation with a
collision error. Aliases may target these flags but may not overload canonical
@@ -202,7 +256,8 @@ libraries retain ownership of their diagnostic detail and disclosure rules.
### Streaming and failure diagnostics
The proposed approach applies visibility when output is emitted. A verbose or
debug run may show progress before subsequently failing, and an ordinary run may
debug run may show informational detail before subsequently failing. A run with
Progress enabled may stream updates before failing, and an ordinary run may
write part of its substantive output before failing. Previously written bytes cannot
be withdrawn. Whole-run buffering solely to make failed runs contain only error
output is not part of the proposed direction.
@@ -220,8 +275,9 @@ end-of-handler presentation, and retain delivery failures. Earlier illustrative
API shapes included `inv.Reporter()`, `Info`, `Warn`, `Diagnostic`, and an
`AtEnd()` view. These names and shapes are exploratory, not selected contracts.
Reassess the necessary API around the output modes and expanded message
categories before adopting them. Debug messages need a corresponding
classification; its exact API remains open.
categories before adopting them. Debug and Progress messages need corresponding
classifications; their exact APIs remain open. Progress is a streaming category;
do not conflate it with deferred informational summaries.
Continue to support standard `io.Writer` usage for report bodies and native
report writers. Reuse existing diagnostic and outcome concepts where practical.
@@ -253,7 +309,8 @@ rules.
1. Settle the open decisions with examples covering ordinary application output,
immediate and deferred diagnostics, failure after partial output, help and
version, and integration diagnostics in every mode.
version, and integration diagnostics in every mode. Include applications that
emit no Progress messages and the distinction between Info and Progress.
2. Review current diagnostic batching, parsing, help, outcome presentation, and
writer ownership to identify the smallest shared changes. Include invocation
failures that occur before a handler receives its `Invocation`.
@@ -267,7 +324,9 @@ rules.
visibility, and write-failure handling with focused behavioral tests and
maintained consumer examples. Cover mode resets, mixed canonical/alias
ordering, help and discovery contexts, and core parser events presented
according to the final mode.
according to the final mode. Cover explicit progress overrides, debug's
progress default, quiet suppression, progress aliases, message prefixes,
and preservation of native multiline diagnostics.
6. Update GoDoc, the CLI reference, consumer guidance, and release documentation
when implemented. Review whether any resulting architectural change needs an
ADR; exact reporting APIs and flag syntax remain API/CLI contracts.
@@ -276,11 +335,13 @@ rules.
### OD-2: Consumer API and output classification
What is the smallest API for substantive output, debug and informational
messages, warnings, and failure diagnostics? How do direct writes through
What is the smallest API for substantive output, streaming progress, debug and
informational messages, warnings, and failure diagnostics? How do direct writes through
`Invocation.Streams` interact with it? How can helpers report through the same
invocation? Is a dedicated immediate/deferred reporter needed, and how does it compose with existing
outcome diagnostics?
How do helpers emit Progress without requiring every application to implement
it or manage verbosity checks themselves?
### OD-3: Failure presentation and diagnostic retention
@@ -293,6 +354,8 @@ Which contextual records belong to an error explanation? How are mixed upstream
diagnostic batches filtered while preserving useful native rendering? What is
retained when presentation is suppressed, and how is duplicate presentation
prevented without hiding unrelated failures?
How do adapters apply the selected prefixes to mixed or already-labelled native
diagnostics? What presentation should streaming Progress use?
### OD-4: Delivery lifecycle and quiet execution
@@ -302,3 +365,6 @@ delivery state represents intentional suppression? Does quiet mode discard
rendered bytes or skip report rendering, and how does that choice preserve
operation semantics and failure detection? Which streaming behavior becomes
part of the public contract?
Are initial Progress messages ordinary streamed lines, or is terminal redraw
behavior needed? How do progress delivery failures and retention interact with
other messages? No progress-bar, redraw, or terminal-specific API is selected yet.