2026-10-23 14:08:10 +00:00
|
|
|
# Output policy and invocation reporting
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
Status: initial planning. Message categories, the quiet/default/verbose output
|
|
|
|
|
policy, and uniform treatment of help and version are selected. A debug mode
|
|
|
|
|
extends the proposed hierarchy. Consumer API, flag details, and delivery
|
|
|
|
|
mechanics remain open. Implementation has not started.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
## Purpose
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
Provide consistent handling of `--quiet`, `--verbose`, and the proposed
|
|
|
|
|
`--debug` mode across application commands and optional integrations. Reduce
|
|
|
|
|
repeated output classification, diagnostic presentation, and delivery bookkeeping
|
|
|
|
|
where CommandKit can provide a meaningful benefit.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
Ordinary Go writers and formatting functions already make application output
|
|
|
|
|
straightforward. Design reporting conveniences around the shared output policy
|
|
|
|
|
and invocation lifecycle. Applications continue to own their report content,
|
|
|
|
|
domain behavior, and operation outcomes.
|
|
|
|
|
|
|
|
|
|
## Current baseline
|
|
|
|
|
|
|
|
|
|
[`Streams` and `Invocation`](../../identity.go) expose caller-selected output
|
|
|
|
|
and diagnostic writers. [`Outcome` and `Diagnostic`](../../outcome.go) carry
|
|
|
|
|
operation causes, diagnostic writers, and delivery state. Handlers can return
|
|
|
|
|
`Failure(err)` or attach diagnostics to an outcome for presentation after the
|
|
|
|
|
handler returns. `MessageDiagnostic` currently writes the supplied message with
|
|
|
|
|
a newline; severity does not add a label automatically.
|
|
|
|
|
|
|
|
|
|
CommandKit coordinates final diagnostic delivery and retains delivery failures
|
|
|
|
|
separately from the operation cause. Custom handlers can also write directly to
|
|
|
|
|
the supplied streams and retain responsibility for their output. The existing
|
|
|
|
|
outcome and channel ownership decisions are recorded in
|
|
|
|
|
[ADR 0005](../adr/0005-invocation-outcomes.md).
|
|
|
|
|
|
|
|
|
|
Integration adapters already translate upstream diagnostic records into
|
|
|
|
|
CommandKit diagnostics while preserving native rendering and source context.
|
|
|
|
|
Some adapters wrap multiple records in one diagnostic writer and classify the
|
|
|
|
|
batch by its highest severity. This matters when designing selective visibility.
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
There is currently no shared verbosity policy or invocation reporter API.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
## Selected output policy
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
Distinguish substantive application output from diagnostic message categories:
|
|
|
|
|
|
|
|
|
|
- **Substantive output (Normal):** The requested report or command result.
|
|
|
|
|
- **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.
|
|
|
|
|
- **Debug:** Troubleshooting detail, including intermediate decisions and
|
|
|
|
|
execution-path information.
|
|
|
|
|
|
|
|
|
|
Quiet, ordinary, and verbose presentation follow the selected policy. The
|
|
|
|
|
proposed debug mode adds troubleshooting detail to verbose output:
|
|
|
|
|
|
|
|
|
|
| Output category | `--quiet` | No flag | `--verbose` | `--debug` (proposed) |
|
|
|
|
|
| --- | --- | --- | --- | --- |
|
|
|
|
|
| Substantive application output | Suppressed | Shown | Shown | Shown |
|
|
|
|
|
| Error | Shown | Shown | Shown | Shown |
|
|
|
|
|
| Warning | Suppressed | Suppressed | Shown | Shown |
|
|
|
|
|
| Info | Suppressed | Suppressed | Shown | Shown |
|
|
|
|
|
| Debug | 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.
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
followed by a successful outcome. The application still controls process exit
|
|
|
|
|
under the existing outcome contract; the returned outcome must consistently
|
|
|
|
|
represent the failure and its non-zero status.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
Apply the same policy to help and version. There are no command-specific
|
|
|
|
|
exceptions for successful output:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
app help --quiet # succeeds silently
|
|
|
|
|
app version --quiet # succeeds silently
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Usage and operational failures still report their errors in quiet mode.
|
|
|
|
|
The feature must distinguish successful output suppression from failure
|
|
|
|
|
diagnostic delivery.
|
|
|
|
|
|
|
|
|
|
## Tentative direction
|
|
|
|
|
|
|
|
|
|
### Flag and invocation behavior
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
Model quiet, ordinary, verbose, and debug as mutually exclusive presentation
|
|
|
|
|
modes. The proposed rule when multiple mode flags occur is last occurrence wins,
|
|
|
|
|
consistent with existing repetition conventions. Exact boolean forms, resets,
|
|
|
|
|
short spellings, placement, and collision handling remain to be specified.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
Keep verbosity a presentation choice: a quiet invocation still performs its
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
### Streaming and failure diagnostics
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
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
|
|
|
|
|
write part of its substantive output before failing. Previously written bytes cannot
|
2026-10-23 14:08:10 +00:00
|
|
|
be withdrawn. Whole-run buffering solely to make failed runs contain only error
|
|
|
|
|
output is not part of the proposed direction.
|
|
|
|
|
|
|
|
|
|
Keep errors understandable in every mode, including source locations and
|
|
|
|
|
related explanatory context. Unrelated warnings and informational messages
|
|
|
|
|
remain subject to the selected mode. Retain suppressed diagnostics for
|
|
|
|
|
programmatic inspection rather than equating suppression with loss of evidence.
|
|
|
|
|
The exact representation of retained and delivered diagnostics remains open.
|
|
|
|
|
|
|
|
|
|
### Consumer reporting API
|
|
|
|
|
|
|
|
|
|
An invocation-scoped facility could classify messages, coordinate immediate and
|
|
|
|
|
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.
|
2026-10-23 18:08:13 +00:00
|
|
|
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.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
Continue to support standard `io.Writer` usage for report bodies and native
|
|
|
|
|
report writers. Reuse existing diagnostic and outcome concepts where practical.
|
|
|
|
|
Any reporting facility should coordinate with returned `Outcome.Diagnostics`
|
|
|
|
|
and operation causes so already-presented messages are not repeated.
|
|
|
|
|
|
|
|
|
|
Whether reporting methods return write errors, retain them for finalization,
|
2026-10-23 18:08:13 +00:00
|
|
|
or expose an explicit delivery-error accessor remains open. The API must enforce
|
|
|
|
|
the selected relationship between Error diagnostics and failed outcomes,
|
|
|
|
|
including diagnostics supplied through generic or existing entry points.
|
2026-10-23 14:08:10 +00:00
|
|
|
|
|
|
|
|
### Upstream diagnostic ownership
|
|
|
|
|
|
|
|
|
|
ConfigKit and PromptKit remain authoritative for their diagnostic semantics,
|
|
|
|
|
severity, source context, and disclosure rules. Integration adapters expose
|
|
|
|
|
those capabilities through the shared CommandKit presentation policy.
|
|
|
|
|
|
|
|
|
|
Support consistent reporting of ConfigKit errors and warnings as its adopted
|
|
|
|
|
public API evolves. This roadmap does not assume that a future warning API
|
|
|
|
|
already exists or prescribe its upstream shape. Preserve useful native
|
|
|
|
|
diagnostic detail and supported error identity, and coordinate returned errors
|
|
|
|
|
with diagnostics that already explain them.
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
Debug output follows the same upstream disclosure and safe-rendering contracts.
|
|
|
|
|
Enabling debug does not authorize secret disclosure or bypass owning-library
|
|
|
|
|
rules.
|
|
|
|
|
|
2026-10-23 14:08:10 +00:00
|
|
|
## Work needed
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
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`.
|
|
|
|
|
3. Specify the public API and flag contracts, including interactions with command
|
|
|
|
|
and flag aliases. Assess existing flag collisions and compatibility impact.
|
|
|
|
|
4. Implement the selected behavior across core and the integrations. Preserve
|
|
|
|
|
upstream rendering and semantics while applying the chosen visibility policy.
|
|
|
|
|
5. Verify classification, flag selection, suppression, retained diagnostics,
|
2026-10-23 18:08:13 +00:00
|
|
|
ordering, duplicate prevention, Error/non-zero-outcome consistency, debug
|
|
|
|
|
visibility, and write-failure handling with focused behavioral tests and
|
|
|
|
|
maintained consumer examples.
|
2026-10-23 14:08:10 +00:00
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
## Open Decisions
|
|
|
|
|
|
|
|
|
|
### OD-1: Flag grammar and scope
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
How are quiet, verbose, and debug selected, repeated, combined, or explicitly
|
|
|
|
|
reset? Are short spellings built in? Where may the flags appear, including on help
|
2026-10-23 14:08:10 +00:00
|
|
|
requests? How are canonical and alias spelling collisions handled, and how is
|
|
|
|
|
the mode determined for invocations that fail during routing or parsing?
|
|
|
|
|
|
|
|
|
|
### OD-2: Consumer API and output classification
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
What is the smallest API for substantive output, 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
|
2026-10-23 14:08:10 +00:00
|
|
|
outcome diagnostics?
|
|
|
|
|
|
|
|
|
|
### OD-3: Failure presentation and diagnostic retention
|
|
|
|
|
|
2026-10-23 18:08:13 +00:00
|
|
|
How does the API enforce that Error diagnostics accompany a failed invocation
|
|
|
|
|
with a non-zero status, including application domain outcomes? How should
|
|
|
|
|
inconsistent caller-supplied combinations be handled through existing diagnostic
|
|
|
|
|
and outcome APIs? How are recovered upstream problems represented as warnings
|
|
|
|
|
while preserving their native context?
|
2026-10-23 14:08:10 +00:00
|
|
|
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?
|
|
|
|
|
|
|
|
|
|
### OD-4: Delivery lifecycle and quiet execution
|
|
|
|
|
|
|
|
|
|
How are immediate and deferred messages ordered and finalized, including when
|
|
|
|
|
the operation fails? How do callers observe and react to write failures? What
|
|
|
|
|
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?
|