diff --git a/docs/roadmap/reporting.md b/docs/roadmap/reporting.md index fae9d1d..19fe3a5 100644 --- a/docs/roadmap/reporting.md +++ b/docs/roadmap/reporting.md @@ -1,14 +1,13 @@ # Output policy and invocation reporting -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. +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. +Consumer API and delivery mechanics remain open. Implementation has not started. ## Purpose -Provide consistent handling of `--quiet`, `--verbose`, and the proposed -`--debug` mode across application commands and optional integrations. Reduce +Provide consistent handling of `--quiet`, `--verbose`, and `--debug` across +application commands and optional integrations. Reduce repeated output classification, diagnostic presentation, and delivery bookkeeping where CommandKit can provide a meaningful benefit. @@ -51,10 +50,9 @@ Distinguish substantive application output from diagnostic message categories: - **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: +Debug mode adds troubleshooting detail to verbose output: -| Output category | `--quiet` | No flag | `--verbose` | `--debug` (proposed) | +| Output category | `--quiet` | No flag | `--verbose` | `--debug` | | --- | --- | --- | --- | --- | | Substantive application output | Suppressed | Shown | Shown | Shown | | Error | Shown | Shown | Shown | Shown | @@ -86,20 +84,121 @@ Usage and operational failures still report their errors in quiet mode. The feature must distinguish successful output suppression from failure diagnostic delivery. -## Tentative direction +## Selected flag grammar and scope -### Flag and invocation behavior +### Mode selection and resets 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. +modes. Each invocation starts in ordinary mode. Process flag occurrences in +invocation order; the last enabled mode wins. Repetition does not increment +verbosity, and debug is selected explicitly. + +Accept presence and the existing explicit boolean syntax, including +`--quiet=true` and `--quiet=false`. A false occurrence clears its mode only if +that mode is currently selected, returning to ordinary mode. It does not restore +an earlier selection or disable a different mode. Every occurrence is converted; +invalid boolean values remain usage errors even when a later flag would replace +the selection. + +| Flag sequence | Final mode | +| --- | --- | +| `--quiet --verbose` | Verbose | +| `--debug --quiet` | Quiet | +| `--verbose --verbose` | Verbose | +| `--verbose --verbose=false` | Ordinary | +| `--quiet --verbose=false` | Quiet | +| `--verbose --quiet --quiet=false` | Ordinary | +| `--quiet=false --debug` | Debug | 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. +### Placement, availability, and aliases + +Core supplies `--quiet`, `--verbose`, and `--debug` 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: + +```text +app config show --quiet +app export destination --verbose +app help config show --quiet +app version --quiet +``` + +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` +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 +spellings. Apply the existing collision and atomic installation rules, including +later registration. + +Aliased and canonical occurrences participate in the same ordering. With +`-q → --quiet`, `app export --verbose -q` selects quiet mode. Document the newly +reserved canonical names as a compatibility change. + +### Routing and parsing failures + +Determine the mode through the normal parser before execution or successful +help/report presentation. Do not add a separate verbosity scanner. This keeps +token interpretation consistent and avoids reinterpreting values or operands. + +Routing and parsing failures report their errors regardless of verbosity. For +example, `app export --quiet --unknown` still reports the unknown flag. Error +visibility follows the selected output policy independently of how the mode is +determined; avoiding a separate scanner is an implementation simplification. + +## CommandKit's own diagnostics + +Use the shared reporting system for CommandKit's invocation diagnostics so +parser, integration, and application messages follow the same visibility and +delivery policy. Installation errors occur before an invocation exists and +continue to be returned to the application without automatic printing. + +Supported repetition and last-occurrence overrides are routine decisions. +Repeated singleton flags, including `--verbose --verbose`, may produce debug +detail; repetition alone does not warrant a warning. Repeatable flags retain +their intended accumulation behavior. Add warnings for concrete concerns an +operator can act on, such as a deprecated spelling if deprecation is introduced. +Unknown flags, invalid values, and invalid command paths remain invocation +failures with error diagnostics. + +Start debug instrumentation with routing, alias resolution, verbosity selection, +and invocation completion. Other useful candidates can be added where they +explain a consequential decision: + +| Event | Useful detail | +| --- | --- | +| Command-alias resolution | Entered path, intermediate redirects, and final canonical path. | +| Flag-alias resolution | Entered spelling and canonical flag name. | +| Scoped alias selection | A command-scoped mapping took precedence over an application-wide mapping. | +| Verbosity selection | A later occurrence selected a different mode; for `--verbose --debug`, debug wins because it appears last. | +| Help-route selection | A canonical command or alias-only discovery context was selected. | +| Repeated singleton flag | A later occurrence replaced an earlier occurrence, without printing their values. | +| Input preparation | Canonical input validation completed and the handler is starting. | +| Invocation completion | Canonical command, outcome classification, and status. | + +Use the final selected mode to present earlier parser decisions. Collect the +relevant events during parsing and apply visibility after mode selection: +`--verbose --debug` shows the selection explanation, while `--debug --quiet` +suppresses it. This collection of parser events does not require whole-run +output buffering. + +Debug messages should explain operator-relevant decisions independently of +incidental implementation steps. Use command paths, flag names, and decision +descriptions rather than raw argument or configuration-value dumps. Upstream +libraries retain ownership of their diagnostic detail and disclosure rules. + +## Tentative direction + ### Streaming and failure diagnostics The proposed approach applies visibility when output is emitted. A verbose or @@ -159,26 +258,22 @@ rules. 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. + and flag aliases, following the selected OD-1 rules above. 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, ordering, duplicate prevention, Error/non-zero-outcome consistency, debug visibility, and write-failure handling with focused behavioral tests and - maintained consumer examples. + maintained consumer examples. Cover mode resets, mixed canonical/alias + ordering, help and discovery contexts, and core parser events presented + according to the final mode. 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 - -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 -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 What is the smallest API for substantive output, debug and informational