Define terminal failure presentation for invocation reporting

This commit is contained in:
2026-10-24 01:19:16 +00:00
parent 0869b17b43
commit 085c296d89

View File

@@ -3,9 +3,9 @@
Status: initial planning. Message categories, all four output modes, uniform
treatment of help and version, message prefixes, and OD-1's flag grammar and
scope (including independent Progress control) are selected.
OD-2's unified reporting direction is selected. Exact API signatures, failure
presentation, retention, and delivery mechanics remain open. Implementation has
not started.
OD-2's unified reporting direction and the terminal failure model are selected.
Exact API signatures, failure explanation details, retention, and delivery
mechanics remain open. Implementation has not started.
## Purpose
@@ -46,7 +46,8 @@ There is currently no shared verbosity policy or invocation reporter API.
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.
- **Error:** Terminal presentation of an unrecoverable invocation failure,
resulting in 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:** Informational context and useful explanation, such as which profile
@@ -76,12 +77,9 @@ 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
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.
Error presentation follows the terminal failure model below. Problems from
which the invocation recovers are warnings, even when an attempted operation
failed internally.
Apply the same policy to help and version. There are no command-specific
exceptions for successful output:
@@ -107,6 +105,37 @@ 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.
### Terminal failure model
During execution, applications can produce substantive output, Progress, Info,
Debug, and Warnings. An unrecoverable failure ends the handler by returning a
failed outcome. There is no standalone `report.Error(...)` method. Detailed
error explanations accompany the returned failure and are presented as part of
that terminal step.
CommandKit finalizes reporting, presents the terminal failure explanation, and
returns the non-zero outcome to the application entry point. It accepts no
further normal output for that invocation after terminal error presentation.
The same boundary applies to core routing and parsing failures that prevent
handler execution. The application entry point retains ownership of process
exit; CommandKit ends the invocation and returns its outcome.
For example, a handler returns immediately on an unrecoverable failure:
```go
result, err := performOperation()
if err != nil {
return commandkit.Failure(err)
}
// Continue normal reporting only after successful operation.
```
Output streamed before the failure remains visible according to its selected
mode; terminal failure does not withdraw earlier bytes. Deferred messages,
cleanup writes, and delivery failures must respect the end of normal reporting.
Their finalization and late-write behavior remain OD-4 details. A terminal
failure may have multiple explanatory records, all belonging to that failure.
## Selected flag grammar and scope
### Mode selection and resets
@@ -300,10 +329,10 @@ diagnostic data for the handler to submit, independently of CommandKit.
The returned outcome owns the operation result: success, failure, or an
application domain classification. CommandKit presents a failed outcome through
the same reporting facility. Error explanations must be explicitly associated
with the failure they describe; an unrestricted `Error(...)` method that permits
success afterward is outside this direction. Typed upstream diagnostic submission
must preserve that relationship as well.
the same reporting facility as the terminal step. Error explanations belong to
that returned failure, including rich upstream explanations. Typed diagnostic
submission must preserve this relationship instead of permitting independently
emitted Error messages during normal execution.
Use the reporter as the common diagnostic submission path, replacing the earlier
proposal to split submission between a reporter and `Outcome.Diagnostics`.
@@ -349,13 +378,15 @@ rules.
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,
ordering, duplicate prevention, Error/non-zero-outcome consistency, debug
ordering, duplicate prevention, terminal Error/non-zero-outcome consistency, debug
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. Cover explicit progress overrides, debug's
progress default, quiet suppression, progress aliases, message prefixes,
and preservation of native multiline diagnostics.
and preservation of native multiline diagnostics. Verify the end of normal
reporting after terminal error presentation, including deferred and late
writes under the selected OD-4 behavior.
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.
@@ -364,12 +395,11 @@ rules.
### OD-3: Failure presentation and diagnostic retention
How does the API enforce that Error diagnostics accompany a failed invocation
with a non-zero status, including application domain outcomes? How should
failure explanations and the operation outcome be associated to avoid
inconsistent caller-supplied combinations? How are recovered upstream problems represented as warnings
while preserving their native context?
Which contextual records belong to an error explanation? How are mixed upstream
The terminal failure model is selected above. How are detailed explanations
attached to the returned failure, including application domain failures? How
are recovered upstream problems represented as warnings while preserving their
native context? Which contextual records belong to a terminal 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?
@@ -379,7 +409,9 @@ diagnostics? What presentation should streaming Progress use?
### 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
the operation fails? How do deferred messages, cleanup writes, and attempts to
use the reporter after terminal failure respect the end of normal reporting?
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