diff --git a/docs/roadmap/reporting.md b/docs/roadmap/reporting.md index 19fe3a5..6d57885 100644 --- a/docs/roadmap/reporting.md +++ b/docs/roadmap/reporting.md @@ -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.