Files
commandkit/docs/adr/0005-invocation-outcomes.md

79 lines
4.0 KiB
Markdown

# ADR 0005: Return explicit outcomes and deliver reports through defined channels
## Status
Accepted.
## Date
2026-10-06
## Context
An invocation crosses routing, parsing, provider acquisition, a standard or
application handler, report writing, and the application entry point. Operators
and subprocess consumers need consistent classifications for those stages.
Applications also have meaningful domain outcomes of their own.
## Decision
CommandKit returns an invocation outcome with an explicit classification and
recommended process status. The public model distinguishes successful operation,
usage error, operational failure, and application domain outcome. Failures retain
their consumer-facing cause and supported `errors.Is`/`errors.As` identity.
Exact Go declarations remain part of facade API design under
[ADR 0003](0003-public-facade.md).
Use these mappings for CommandKit-owned commands:
| Status | Meaning |
| --- | --- |
| `0` | The requested operation completed successfully. |
| `1` | A syntactically valid operation failed during loading, validation, lookup, inspection, cancellation, diagnostics delivery, or report writing. |
| `2` | The invocation failed command, flag, scope, format, operand, or input-combination validation. |
CommandKit's handler result contract accepts domain classifications and suggested
process statuses supplied by the caller. CommandKit preserves that classification
when returning the handler's result. A custom domain status and a shared usage
status may have the same numeric value; their explicit classifications retain
their distinct meanings. The application entry point controls final process
termination and status mapping.
CommandKit writes standard reports to the supplied report stream, conventionally
stdout, and its warnings and errors to the supplied diagnostic stream,
conventionally stderr. Callers choose the streams. CommandKit assigns responsibility
for presenting its diagnostics, avoids duplicate presentation through its own
paths, and reports write failures. Caller callbacks retain control of their own
output. CommandKit adapts backend syntax failures into its public classification
and diagnostic presentation. Usage guidance accompanies usage errors; operational
failures receive diagnostics appropriate to the failed operation.
Warning severity alone permits a successful operation. A diagnostic writer
failure is an operational failure.
A writer failure can leave a partial report and returns operational failure. The
outcome identifies incomplete delivery. Custom handler output remains
application-owned. [ADR 0007](0007-native-yaml-reports.md) covers `config show` report
preparation; [ADR 0008](0008-semantic-configuration-diff.md) defines successful
comparison outcomes.
## Alternatives considered
| Alternative | Analysis |
| --- | --- |
| A single failure classification | Simplifies outcome handling. Callers derive syntax, operational, and domain distinctions through additional interpretation. |
| Backend errors and output as the public outcome model | Reuses framework machinery directly. Backend conventions become dependencies for applications and subprocess consumers. |
| One common mapping for application domain failures | Produces uniform numeric statuses. Applications adapt existing artifact and execution outcomes to shared categories. |
| Handler-owned diagnostics for every failure | Gives each handler full presentation control. Shared diagnostic consistency requires repeated ownership and formatting coordination. |
## Consequences
The outcome model supports both Go callers and executable entry points. Explicit
classification keeps domain identity intact through adapter and facade conversion.
Single diagnostic ownership supports predictable presentation.
The public result/error design must preserve cause and delivery failures across
handlers, writers, and the backend adapter. Diagnostic delivery bookkeeping
remains API design work. Acceptance establishes the compatibility meaning of the
status values and delivery rules across standard commands.