Plan invocation reporting implementation
This commit is contained in:
682
docs/roadmap/implementation.md
Normal file
682
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,682 @@
|
||||
# Invocation reporting implementation plan
|
||||
|
||||
Status: ready for implementation. No implementation stages are complete.
|
||||
|
||||
## Objective and authority
|
||||
|
||||
Implement the end state selected in the [reporting roadmap](reporting.md), under
|
||||
[ADR 0014](../adr/0014-invocation-reporting.md),
|
||||
[ADR 0005](../adr/0005-invocation-outcomes.md), and the
|
||||
[architecture policy](../policy/architecture.md). The roadmap owns the selected
|
||||
behavior and target API; this document owns the steps from the current code to
|
||||
that end state. Read those sources before starting.
|
||||
|
||||
CommandKit owns presentation, invocation coordination, and its own failures.
|
||||
Applications own their domain responses and selected outcomes. ConfigKit and
|
||||
PromptKit own their native semantics, diagnostic evidence, and disclosure rules.
|
||||
The [testing policy](../policy/testing.md#upstream-integration-testing-ownership)
|
||||
applies to every stage: test CommandKit's adaptation and presentation, without
|
||||
retesting upstream functionality.
|
||||
|
||||
## Sprint instructions
|
||||
|
||||
- Follow the stages in order. Each stage is sized as a separate Luna task.
|
||||
Read the entire plan initially and the owning roadmap sections for each stage.
|
||||
- This is one end-to-end sprint. Intermediate stages need not compile or leave
|
||||
the repository coherent. Reach the clean final API directly; do not introduce
|
||||
compatibility constructors, duplicate submission paths, or temporary adapters
|
||||
merely to make intermediate commits buildable.
|
||||
- Preserve behavior outside the selected reporting changes, including command
|
||||
and flag aliases, typed input semantics, provider lifetimes, scope selection,
|
||||
native reports, and optional-module dependency direction.
|
||||
- Inspect existing tests before adding coverage. Migrate tests whose contracts
|
||||
intentionally change; retain protection for unaffected behavior. Each stage's
|
||||
validation list identifies risks to protect, not a requirement for one test
|
||||
per bullet or an exhaustive cross product.
|
||||
- Add or revise focused tests with the owning implementation. Run executable
|
||||
focused checks when their dependencies are ready. Record deferred validation
|
||||
accurately; a broken intermediate build is not evidence of a passing test.
|
||||
Stage 20 validates the assembled repository.
|
||||
- Follow the [agent policy](../policy/agents.md), including focused local commits
|
||||
and preservation of unrelated changes. Update this plan's stage status as work
|
||||
completes. Do not push, tag, publish, or retire these planning documents as
|
||||
part of this sprint.
|
||||
|
||||
## Baseline and implementation boundaries
|
||||
|
||||
At planning baseline `1d29cdd`, core handlers receive raw `Invocation.Streams`.
|
||||
`Outcome` combines causes, queued diagnostics, and older delivery fields.
|
||||
`execution.present` coordinates final diagnostics. The Cobra adapter returns
|
||||
per-binding flag values and spellings, but not their order across different
|
||||
flags. Reporting modes and an invocation reporter do not exist.
|
||||
|
||||
Core remains responsible for the public reporter, outcome types, visibility,
|
||||
delivery accounting, flag policy, and automatic finalization. Keep ordinary
|
||||
private implementation beside the root facade where appropriate; introducing a
|
||||
new public package is unnecessary. `internal/commandmeta` carries neutral parser
|
||||
metadata, and `internal/cobra` continues to contain Cobra/pflag-specific code.
|
||||
|
||||
`integrations/ckconfig` owns ConfigKit adaptation and configuration command
|
||||
presentation. `integrations/ckprompt` owns PromptKit adaptation and commands and
|
||||
may use ckconfig. Neither integration becomes a dependency of core, and ckconfig
|
||||
does not import ckprompt. Providers return passive data; they do not acquire a
|
||||
reporter parameter.
|
||||
|
||||
Use one shared private state per reporter and serialize operations with a mutex.
|
||||
Use synchronous writes rather than adding a buffering or worker subsystem.
|
||||
Render callbacks receive a writer for the already-coordinated operation; that
|
||||
writer must not reacquire the reporter lock. Callback reentrancy restrictions
|
||||
are those selected in the roadmap, without runtime detection machinery.
|
||||
|
||||
## Stage 1: Replace outcome and provider data declarations
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [outcome.go](../../outcome.go) and their focused contract tests.
|
||||
|
||||
1. Implement the exact `Explanation`, `Outcome`, `PresentationResult`,
|
||||
`DeliveryResult`, and `DeliveryState` declarations selected in the roadmap.
|
||||
Use the selected `uint8` delivery enumeration, including `DeliverySuppressed`.
|
||||
Remove the superseded outcome diagnostic/delivery fields.
|
||||
2. Implement `Success`, `Failure(message, details...)`, `Usage(message,
|
||||
details...)`, `Domain(name, status)`, `WithExplanation`, and `WithCause`.
|
||||
Copy accepted detail slices so replacing or modifying the caller's slice
|
||||
does not change a captured callback list. Callback-captured data remains
|
||||
caller-owned. Constructors and modifiers emit nothing.
|
||||
3. Preserve optional `Cause` unchanged. It does not select status, category, or
|
||||
explanation. Preserve zero-value outcome success without treating a cause
|
||||
as a reason to infer failure. `WithExplanation` preserves cause;
|
||||
`WithCause` preserves classification, status, and explanation.
|
||||
4. Add `Explanation` to `Acquired[T]`. Keep `Diagnostic` as passive severity and
|
||||
renderer data. Retain `SeverityWarning` and add `SeverityInfo`,
|
||||
`SeverityDebug`, and `SeverityProgress`; remove `SeverityError` because
|
||||
terminal content now belongs to `Explanation`. Retain `MessageDiagnostic`
|
||||
as a passive literal-message renderer helper, without emitting or selecting
|
||||
an outcome.
|
||||
5. Declare `ErrReporterClosed` with the selected error text. Do not retain the
|
||||
old API through overloaded or parallel constructors.
|
||||
|
||||
Validation: protect constructor/modifier independence, copied callback lists,
|
||||
non-emission, and cause identity using `errors.Is` and `errors.As`. Existing
|
||||
callers are migrated in later stages.
|
||||
|
||||
## Stage 2: Implement reporter state and managed output writers
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: new private reporting implementation in core, plus
|
||||
[identity.go](../../identity.go) as needed for internal wiring.
|
||||
|
||||
1. Add the public `Reporter` facade backed by one private invocation state.
|
||||
Its private constructor accepts caller-selected destinations and starts in
|
||||
ordinary mode. Keep `Streams` as the `App.Execute` input; preserve existing
|
||||
nil-destination normalization.
|
||||
2. Implement `Output()` using a managed `io.Writer`. Serialize each write,
|
||||
preserve ordinary writer return behavior, and record the first destination
|
||||
failure even if the handler ignores it. Normalize a short write with nil
|
||||
error to `io.ErrShortWrite`.
|
||||
3. Track result and diagnostic destinations independently. A failed destination
|
||||
receives no more writes; a healthy destination remains usable. Keep the
|
||||
first render error and first write error per destination, without a history
|
||||
or content buffer.
|
||||
4. Implement private visibility state for ordinary, quiet, verbose, and debug,
|
||||
plus explicit progress value and presence. Quiet output writes discard
|
||||
bytes successfully without calling the supplied destination.
|
||||
5. Aggregate delivery observations according to the roadmap: incomplete when
|
||||
rendering or writing failed; otherwise complete when requested delivery
|
||||
completed, suppressed when all submitted content was hidden, and none when
|
||||
no content was submitted. Merely obtaining an output handle submits nothing.
|
||||
6. Retained output handles consult shared lifecycle state on every write.
|
||||
After closure they return `ErrReporterClosed`, including under quiet mode.
|
||||
Do not close or automatically flush caller-owned destinations.
|
||||
|
||||
Validation: use controlled writers to cover visible and suppressed output,
|
||||
short writes, ignored errors, bounded first-error retention, destination
|
||||
independence, and retained-handle closure. No concurrent `App.Execute` support is
|
||||
introduced by reporter synchronization.
|
||||
|
||||
## Stage 3: Implement atomic rendering and categorized messages
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Implement `RenderOutput`, `Info`, `Warn`, `Debug`, and `Progress` with the
|
||||
exact roadmap signatures. A render operation or complete categorized message
|
||||
owns the reporting lock for its heading and all details.
|
||||
2. Render callbacks through their supplied writer. The internal writer records
|
||||
destination failures without recursively locking the reporter. Multiple raw
|
||||
`Output().Write` calls remain separate operations.
|
||||
3. Implement literal headings, the selected prefixes and channels, newline
|
||||
termination, empty-heading behavior, and ordered details. Skip nil details.
|
||||
Preserve native multiline content and distinct submissions with equal text.
|
||||
4. Apply the selected visibility table and progress precedence. Suppressed rich
|
||||
renderers execute against discard initially; simple hidden headings need no
|
||||
formatting or destination write. Do not retain hidden content.
|
||||
5. Record callback failures as presentation failures even when ignored. Distinguish
|
||||
them from sink failures: a callback error alone does not mark the destination
|
||||
unusable. A propagated managed-writer error is evidence of the write failure,
|
||||
not a second independently discovered rendering failure; independently
|
||||
returned renderer errors remain available separately.
|
||||
6. Keep the directly invoked encoder boundary: an encoder called by application
|
||||
code on `Output()` owns its encoding error, while managed writer errors are
|
||||
still tracked. CommandKit owns callback errors from `RenderOutput` and details.
|
||||
|
||||
Validation: cover category visibility and destination, prefixes, empty/native
|
||||
headings, detail order, rendering failure before any write, rendering failure
|
||||
under quiet mode, and independent rendering/write failures. Exercise concurrent
|
||||
complete messages and rendering operations with deterministic synchronization;
|
||||
assert intact operations without imposing an order among concurrent callers.
|
||||
|
||||
## Stage 4: Implement deferred delivery and finalization
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Implement `AtEnd` and the selected value-type `DeferredReporter` methods.
|
||||
Copy callback lists on submission. Queue messages in submission order,
|
||||
without sorting by severity or retaining a delivered transcript.
|
||||
2. Implement one private finalization path: drain eligible deferred messages;
|
||||
finish ordinary reporting including the completion event supplied later;
|
||||
account for failures; present the terminal explanation; close the reporter;
|
||||
populate and return `Outcome.Presentation`.
|
||||
3. Deferred messages remain eligible on failure. Handler Go defers run before
|
||||
finalization. Applications finish reporting goroutines before returning;
|
||||
this is not a task-waiting or cancellation subsystem.
|
||||
4. Before terminal delivery, insert and retain `Command failed.` only for a
|
||||
non-zero status with an empty heading and no non-nil detail callback.
|
||||
Trust a supplied renderer even if it emits no bytes. Do not inspect its
|
||||
output by buffering or replaying it.
|
||||
5. Apply the selected failure table: any presentation failure changes a standard
|
||||
outcome, including usage, to operational status `1`. Preserve domain name
|
||||
and non-zero status; change domain status `0` to `1`. Preserve the original
|
||||
explanation and optional cause, recording presentation evidence separately.
|
||||
6. If presentation failure turns success into failure without an explanation,
|
||||
supply a useful core-owned explanation through a healthy diagnostic
|
||||
destination. Never derive application text from `Cause`, redirect failed
|
||||
diagnostics into results, or recursively report a broken diagnostic sink.
|
||||
7. Terminal delivery failures update observations and outcome classification
|
||||
without scheduling another terminal explanation. Close every shared handle
|
||||
before returning. Clear consumed deferred/parser state.
|
||||
|
||||
Validation: cover immediate/deferred/terminal ordering, deferred failures,
|
||||
generic fallback and retention, explicit zero-byte native explanations,
|
||||
success/usage/operational/domain transitions, preserved causes and explanations,
|
||||
healthy diagnostic delivery following renderer failure, and closed retained
|
||||
reporter/deferred/output handles. Include failures during terminal delivery.
|
||||
|
||||
## Stage 5: Install shared reporting flag metadata
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [command.go](../../command.go),
|
||||
[parser.go](../../parser.go), [flag_aliases.go](../../flag_aliases.go),
|
||||
[help_view.go](../../help_view.go), and
|
||||
[internal/commandmeta/metadata.go](../../internal/commandmeta/metadata.go).
|
||||
|
||||
1. Define shared neutral metadata for the four long boolean flags: `quiet`,
|
||||
`verbose`, `debug`, and `progress`. Supply it to every parse/help context:
|
||||
root, canonical groups, runnable commands, built-ins, and alias-only discovery.
|
||||
Keep Cobra/pflag declarations inside the adapter.
|
||||
2. Extend reserved-name validation to those four long names. Preserve capture
|
||||
error retention, installation collision reporting, and batch atomicity,
|
||||
including later registration. Do not reserve unselected short spellings.
|
||||
3. Include core flags among alias targets and canonical spelling collisions in
|
||||
every applicable context. Applications may register their own short aliases
|
||||
through the existing API; core supplies none for reporting flags.
|
||||
4. Keep reporting flags separate from consumer typed bindings. Do not shift
|
||||
`BindingSet` identities or change the number/order of values supplied to a
|
||||
captured input preparer.
|
||||
5. Extend help metadata without manufacturing canonical nodes for discovery
|
||||
contexts or changing entered/canonical identity rules.
|
||||
|
||||
Validation: protect installation collisions and atomicity, aliases to each core
|
||||
flag, canonical-spelling collisions, unchanged typed binding indexes, and flag
|
||||
availability in root/group/built-in/discovery help.
|
||||
|
||||
## Stage 6: Preserve occurrence order through the normal parser
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [internal/cobra/flags.go](../../internal/cobra/flags.go),
|
||||
[internal/cobra/parse.go](../../internal/cobra/parse.go), and neutral metadata.
|
||||
|
||||
1. Extend the neutral parse result with ordered flag-occurrence evidence carrying
|
||||
canonical flag identity, entered spelling, and raw value. Keep existing
|
||||
per-binding values and spelling information for typed inputs.
|
||||
2. Record occurrences when the normal parser consumes flags, using the existing
|
||||
alias interpreter and raw-value collection. Do not add a second raw-argv
|
||||
scanner for verbosity. Preserve the consumed prefix when parsing fails;
|
||||
do not invent occurrences after the failing token.
|
||||
3. Reduce reporting occurrences in argv order. Convert every supplied boolean,
|
||||
including overwritten occurrences. True selects its mode; false clears only
|
||||
the currently selected matching mode to ordinary. Track the last explicit
|
||||
progress value and its presence independently.
|
||||
4. Ensure aliased and canonical spellings share one order, including existing
|
||||
short-alias clusters and boolean syntax. Keep option-looking flag values,
|
||||
operands after `--`, and ordinary consumer flag values unchanged.
|
||||
5. Preserve command-path placement rules, interspersed operands after the
|
||||
complete path, existing failure precedence where unaffected, and help
|
||||
boolean handling. Unknown flags and invalid booleans remain usage failures.
|
||||
6. Make the resolved presentation selection and relevant neutral parser events
|
||||
available to core before output or input factories run. Partial selection
|
||||
on failure must not affect unconditional terminal-error visibility.
|
||||
|
||||
Validation: own the dense ordering cases at the parser/reducer boundary: every
|
||||
roadmap reset example, mixed aliases, repeated booleans, invalid earlier values,
|
||||
explicit progress before/after mode flags, values containing reporting-like
|
||||
tokens, terminators, and malformed paths. Retain coverage for input spelling
|
||||
provenance and consumer binding conversion.
|
||||
|
||||
## Stage 7: Connect invocation execution to one reporter
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [identity.go](../../identity.go),
|
||||
[execute.go](../../execute.go), [route.go](../../route.go),
|
||||
[flag_values.go](../../flag_values.go), and their invocation tests.
|
||||
|
||||
1. Replace handler-facing `Invocation.Streams` with a private reporter reference
|
||||
and the public `Invocation.Reporter()` method. Retain context and entered/
|
||||
canonical accessors. `App.Execute` continues accepting caller `Streams`.
|
||||
2. Construct one reporter for every invocation, including paths that fail before
|
||||
a handler exists. Apply parsed selection before successful output, input
|
||||
preparation, providers, or the handler.
|
||||
3. Replace old `present` bookkeeping with the single finalization path. Route
|
||||
every normal return through it: nil application/context errors, route and
|
||||
parse failures, preparation failures, group/help results, and handler outcomes.
|
||||
4. Convert CommandKit-owned errors deliberately into the new message-first
|
||||
constructors, preserving applicable cause identity with `WithCause`.
|
||||
Preserve `ErrFlagInput`/`ErrFlagWiring` classification and input validation.
|
||||
Do not use a generic rule that turns any application cause into terminal text.
|
||||
5. Attach usage guidance as terminal explanation detail, visible under quiet.
|
||||
Preserve entered alias paths, custom discovery usage, and the distinction
|
||||
between unresolved routes and canonical command identity.
|
||||
6. Populate presentation observations from actual reporter state rather than
|
||||
accepting handler-supplied observation fields as delivery evidence.
|
||||
Preserve fresh input/state lifetimes and registration from handlers; a
|
||||
refreshed registry snapshot must not replace the invocation's reporter.
|
||||
|
||||
Validation: exercise early failures, handler success and domain outcomes,
|
||||
cleanup writes, ignored writer failures, repeated invocations, alias identity,
|
||||
and usage guidance in quiet. Preserve factory-free help/preflight behavior and
|
||||
existing input conversion/cause tests under the new API.
|
||||
|
||||
## Stage 8: Migrate help and version presentation
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [builtins.go](../../builtins.go), help metadata/rendering,
|
||||
and built-in consumer tests.
|
||||
|
||||
1. Route successful help and version results through substantive reporting.
|
||||
Quiet success emits neither report nor a terminal explanation.
|
||||
2. Keep help-path validation and invalid component/version selection as usage
|
||||
handling. An unknown help target must not become a rendering failure merely
|
||||
because help uses `RenderOutput` for presentation.
|
||||
3. Put actual help/version rendering and delivery under managed reporting,
|
||||
using the supplied callback writer. Preserve the internal backend boundary
|
||||
and discovery help metadata. Render quietly into discard where required.
|
||||
4. Keep application version as the default and existing explicit component
|
||||
selection intact. Do not add new version scopes or dependency inspection.
|
||||
5. Remove built-in paths that write directly to invocation streams or manually
|
||||
populate superseded incomplete-report fields.
|
||||
|
||||
Validation: cover `help --quiet`, `version --quiet`, canonical and alias help,
|
||||
alias-only discovery, shared reporting flags, invalid help/version requests,
|
||||
factory-free behavior, and help/version destination failures. Invalid requests
|
||||
remain usage outcomes unless presentation subsequently fails.
|
||||
|
||||
## Stage 9: Add core debug events
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Instrument routing, command-alias resolution, verbosity selection, and handler
|
||||
completion. Explain the relevant entered/canonical paths and decisions.
|
||||
Include flag-alias identity when it explains reporting selection.
|
||||
2. Collect early routing/parser events temporarily and submit them only after
|
||||
final mode selection. Clear them after submission; do not add a transcript.
|
||||
3. Submit the completion event after the handler returns and after deferred
|
||||
messages, before terminal presentation. Describe the handler's classification
|
||||
and status; the returned outcome remains authoritative after delivery.
|
||||
4. Use shared Debug reporting for events and normal presentation failure handling
|
||||
for their delivery. Do not dump argv values, configuration values, causes, or
|
||||
provider objects. Installation errors remain ordinary returned Go errors.
|
||||
5. Other candidate events in the roadmap are opportunities, not mandatory
|
||||
instrumentation for every internal step. Do not turn supported repetition
|
||||
into a warning.
|
||||
|
||||
Validation: `--verbose --debug` reveals earlier selection events;
|
||||
`--debug --quiet` hides them. Cover alias paths, completion before terminal
|
||||
explanation, absence of completion when no handler runs, and debug delivery
|
||||
failure. Assert selected meaning and order rather than incidental prose.
|
||||
|
||||
## Stage 10: Separate ConfigKit provider messages and explanations
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files:
|
||||
[configkit_adapter.go](../../integrations/ckconfig/configkit_adapter.go),
|
||||
[contracts.go](../../integrations/ckconfig/contracts.go), and adapter tests.
|
||||
|
||||
1. Migrate `FromConfigKit`, comparison acquisition, and diagnostic helpers to
|
||||
`Acquired.Diagnostics` plus `Acquired.Explanation`. Public provider callbacks
|
||||
remain passive and retain their existing context/request/input/state shape.
|
||||
2. Replace highest-severity whole-batch promotion. Partition native records into
|
||||
independent nonterminal messages and identified terminal context. Native
|
||||
error records belong to the explanation; independent warnings remain warnings.
|
||||
Preserve explicitly related native context with its owning record.
|
||||
3. Preserve native diagnostic writers, source identifiers/legends, selected
|
||||
scope and comparison-side context, safe disclosure, and record order within
|
||||
each resulting presentation path. Snapshot renderer inputs as needed for
|
||||
deferred use; do not infer relationships from text or error-chain wording.
|
||||
4. Preserve data returned alongside errors and supported Go error identity.
|
||||
A native terminal explanation must not also be submitted as an independent
|
||||
diagnostic or repeated through a generic cause-derived message.
|
||||
5. Preserve comparison left/right preparation and failure behavior. Carry
|
||||
already-acquired independent messages through a later acquisition failure.
|
||||
|
||||
Validation: adapter tests establish faithful record separation, source/side
|
||||
context, passive acquisition, retained causes, and data alongside errors.
|
||||
Use native results as fixtures without testing ConfigKit's resolution or
|
||||
diagnostic classification algorithms.
|
||||
|
||||
## Stage 11: Migrate configuration show and validate
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [show.go](../../integrations/ckconfig/show.go),
|
||||
[validate.go](../../integrations/ckconfig/validate.go), and
|
||||
[operations.go](../../integrations/ckconfig/operations.go).
|
||||
|
||||
1. Introduce small integration-private helpers to submit passive diagnostics to
|
||||
the corresponding reporter methods, using the deferred view for end-of-run
|
||||
warnings/context. Native fully formatted renderers use empty headings.
|
||||
Progress, if present, is immediate; no deferred Progress API is added.
|
||||
2. Replace old `configOperationFailure`/incomplete-report bookkeeping with explicit
|
||||
explanations, optional original causes, and reporter-owned delivery evidence.
|
||||
Use an acquired native explanation when available; otherwise select a useful
|
||||
integration-owned operation explanation. Do not add a second cause printout.
|
||||
3. Migrate `config show` to managed rendering. Preserve loading all selected
|
||||
views before any report output, single-scope native YAML, and ordered
|
||||
`--scope all` framing, including existing directive/document handling.
|
||||
Keep necessary per-document buffers; do not introduce whole-run buffering.
|
||||
4. Include serialization, native rendering, and framing inside the managed
|
||||
rendering operation so callback failures are recorded under quiet as well.
|
||||
Report additional messages outside callbacks through the reporter.
|
||||
5. Migrate `config validate`, including selected-scope iteration, result records,
|
||||
acquisition failure, and terminal explanation. Preserve existing request and
|
||||
invocation-state lifetimes, cancellation, and preflight selection.
|
||||
|
||||
Validation: preserve show YAML/framing and load-before-output protections.
|
||||
Add representative mixed warning/failure visibility in ordinary/verbose/quiet,
|
||||
deferred context ordering, rendering failures, and report write failures.
|
||||
Update tests of superseded outcome fields to observable reports and
|
||||
`Presentation`, rather than dropping their original failure protection.
|
||||
|
||||
## Stage 12: Migrate configuration sources, explain, and diff
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [sources.go](../../integrations/ckconfig/sources.go),
|
||||
[explain.go](../../integrations/ckconfig/explain.go),
|
||||
[diff.go](../../integrations/ckconfig/diff.go), and remaining report helpers.
|
||||
|
||||
1. Migrate remaining commands to the same reporting helpers and deliberate
|
||||
operation explanations. Preserve scope availability, selection, source
|
||||
evidence, redaction, and ConfigKit-owned comparison semantics.
|
||||
2. Wrap the complete CommandKit-owned report rendering in `RenderOutput`,
|
||||
including preparation/encoding that can fail before destination writes.
|
||||
Keep existing safe diff YAML and changed/deleted-field presentation.
|
||||
3. Submit independent provider messages once and attach terminal explanation
|
||||
only to the returned failed outcome. Preserve partial results already
|
||||
delivered according to each command's existing behavior.
|
||||
4. Remove obsolete integration delivery flags, outcome diagnostic attachment,
|
||||
manual writer tracking, and helpers superseded by the shared reporter.
|
||||
Preserve meaningful operation causes; do not assign a presentation error as
|
||||
the operation cause merely to reproduce old bookkeeping.
|
||||
|
||||
Validation: retain comparison preflight, selector, safe-report, and native
|
||||
forwarding tests. Cover a representative failure on each destination and quiet
|
||||
rendering without duplicating core's complete visibility matrix in every command.
|
||||
|
||||
## Stage 13: Migrate PromptKit acquisition adapters
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [adapters.go](../../integrations/ckprompt/adapters.go),
|
||||
[validation.go](../../integrations/ckprompt/validation.go),
|
||||
[smoke.go](../../integrations/ckprompt/smoke.go), and provider contracts.
|
||||
|
||||
1. Carry passive independent diagnostics and terminal explanation separately
|
||||
through engine loading, definition/requirements acquisition, request
|
||||
validation, and smoke acquisition. Use a private acquisition bundle where
|
||||
necessary to avoid losing either field between helpers.
|
||||
2. Replace mixed-batch severity promotion while preserving native rendering,
|
||||
primary/related source context, source legends, scope/side labels, and
|
||||
disclosure. Keep unrelated warnings out of terminal explanations.
|
||||
3. Update `ConfigScope` and engine comparison to use the migrated ckconfig
|
||||
contracts. Keep dependency direction ckprompt to ckconfig.
|
||||
4. Preserve original returned errors, useful reports alongside errors, native
|
||||
validation/smoke evidence, builder/preflight order, and selected request
|
||||
lifetimes. Providers remain independent of the reporter.
|
||||
5. Use upstream APIs as adopted. Do not add probes, diagnostic interpretation,
|
||||
extra inference calls, capability warnings, or newly required configuration.
|
||||
|
||||
Validation: establish correct forwarding, passive data, separated context,
|
||||
and supported error identity. Preserve offline fixtures and existing builder/
|
||||
acquisition lifecycle protections. No live provider or credentials are needed.
|
||||
|
||||
## Stage 14: Migrate PromptKit listing and inspection commands
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary file: [command.go](../../integrations/ckprompt/command.go) and its
|
||||
catalog, definition, and requirements report helpers/tests.
|
||||
|
||||
1. Migrate catalog listing, definition inspection, and requirements inspection
|
||||
to the reporter, replacing raw stream writes and old `definitionFailure`
|
||||
diagnostic bookkeeping.
|
||||
2. Submit independent diagnostics once through small integration-private
|
||||
category helpers; use acquired terminal context on failure and preserve
|
||||
optional original causes. Native labelled detail uses an empty heading.
|
||||
3. Enclose report preparation, native rendering/encoding, and delivery in
|
||||
managed rendering where CommandKit invokes them. Quiet runs still discover
|
||||
report-generation failures without touching caller result destinations.
|
||||
4. Preserve native optional/version fields, text/YAML formats, selection,
|
||||
aliases, request bindings, and command availability. The reporting feature
|
||||
does not change what an inspection means or which APIs it invokes.
|
||||
|
||||
Validation: migrate existing report/selection tests; add representative
|
||||
successful quiet/verbose/debug execution and native acquisition failure with an
|
||||
independent warning. Reuse core reporting coverage for universal mechanics.
|
||||
|
||||
## Stage 15: Migrate request validation and smoke commands
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files:
|
||||
[validation_command.go](../../integrations/ckprompt/validation_command.go) and
|
||||
[smoke_command.go](../../integrations/ckprompt/smoke_command.go).
|
||||
|
||||
1. Migrate concrete requirements validation to managed output, passive-message
|
||||
submission, explicit terminal explanation, and optional cause transport.
|
||||
Preserve its native report and established status decisions.
|
||||
2. Migrate each `promptkit test` command and `test all`. Keep the established
|
||||
four-test order, aggregate request/state reuse, continuation/stop behavior,
|
||||
cancellation, and operation-error handling except for selected shared
|
||||
presentation changes.
|
||||
3. Preserve a substantive smoke report returned alongside an operation error.
|
||||
Render it before finalization, then attach the terminal explanation. Under
|
||||
quiet, render into discard while retaining terminal failure visibility.
|
||||
4. Preserve aggregate collection before its single report is encoded and
|
||||
submitted. Move aggregate encoding and writing into managed rendering;
|
||||
do not introduce per-test streaming or change which native tests run because
|
||||
presentation now uses a reporter. Replace old `smokeDeliveryFailure` flags
|
||||
with reporter evidence, preserving operation causes and explanations
|
||||
independently of presentation failures.
|
||||
5. Remove obsolete manually tracked delivery state. Do not reinterpret native
|
||||
supported/completed/result fields or add unsolicited warnings.
|
||||
|
||||
Validation: use offline stubs/native fixtures to protect aggregate order and
|
||||
bindings, reports alongside errors, diagnostic ordering, cancellation,
|
||||
render/write failures, and quiet semantics. Test CommandKit coordination,
|
||||
not whether PromptKit's validation or smoke checks implement their domain rules.
|
||||
|
||||
## Stage 16: Maintain a core reporting consumer
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary files: [examples/core/main.go](../../examples/core/main.go) and its
|
||||
existing example tests.
|
||||
|
||||
1. Migrate current custom commands to `Invocation.Reporter()` while preserving
|
||||
their existing input and alias demonstrations.
|
||||
2. Add one small application-owned reporting demonstration to this existing
|
||||
example, using deterministic local operations/fixtures. Demonstrate ordinary
|
||||
result rendering, optional Warning and Info, Progress, Debug, and a deferred
|
||||
summary. Avoid adding another module or an external service.
|
||||
3. Provide simple selectable scenarios for silent recovery, an explicit warning
|
||||
with/without a Go error, and a terminal explanation without a cause. Include
|
||||
failure after partial output and optional cause transport independent of text.
|
||||
4. Show rendering helpers using their supplied callback writer and additional
|
||||
message submissions outside callbacks. Keep examples focused on public usage;
|
||||
delivery accounting mechanics belong in tests/internal documentation.
|
||||
|
||||
Validation: keep the example runnable offline and cover representative modes
|
||||
and failure paths with its owning suite. Use package tests for detailed cause
|
||||
identity and delivery states rather than expanding the example into a framework.
|
||||
|
||||
## Stage 17: Migrate maintained integration consumers
|
||||
|
||||
Status: pending.
|
||||
|
||||
Primary directories:
|
||||
[ckconfig example](../../integrations/ckconfig/examples/simple) and
|
||||
[composed PromptKit example](../../integrations/ckprompt/examples/composed).
|
||||
|
||||
1. Migrate custom handlers and provider diagnostics to the selected APIs.
|
||||
Preserve composition, aliases, configuration scopes, input/state sharing,
|
||||
and the offline smoke client/fixtures.
|
||||
2. Ensure examples demonstrate independent provider warnings separately from
|
||||
native terminal context where applicable. Do not add artificial upstream
|
||||
capabilities merely to produce every message category.
|
||||
3. Adapt their existing tests to reporters and presentation observations while
|
||||
retaining native YAML, discovery, and custom-command behavior protections.
|
||||
4. Exercise ordinary/quiet configuration output, a verbose provider warning,
|
||||
aliased help, and a smoke report plus terminal failure using controlled
|
||||
fixture evidence. Avoid multiplying identical mode cases across all commands.
|
||||
|
||||
Validation: both example packages compile in their owning modules and run
|
||||
without external services. Confirm custom commands and integration commands
|
||||
share the same reporting flags and terminal behavior.
|
||||
|
||||
## Stage 18: Reconcile the full test suite and architectural boundaries
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Find and migrate remaining callers of removed constructors, raw invocation
|
||||
streams, terminal `SeverityError`, outcome diagnostic submission, and old
|
||||
delivery fields across tests, benchmarks, and supporting code. `Streams`
|
||||
supplied to `Execute` remains valid; passive provider diagnostics remain valid.
|
||||
2. Preserve regression coverage for alias routing, discovery, installation
|
||||
atomicity, typed presence/false/zero values, invocation freshness, help without
|
||||
loading, native report contracts, cancellation, and supported error identity.
|
||||
Update expectations only where the selected reporting behavior changes them.
|
||||
3. Consolidate reporting coverage at its owning boundary. Include all selected
|
||||
delivery states, first-error retention per destination, ignored immediate
|
||||
failures, deferred/terminal failures, domain status handling, caller-writer
|
||||
ownership, late handles in quiet, and healthy sinks after renderer failure.
|
||||
4. Verify reporter operations are safe concurrently and keep complete messages/
|
||||
callbacks intact. Use coordination primitives rather than sleeps or assumed
|
||||
scheduling. Do not test recursive reporter callbacks as supported use or
|
||||
infer concurrent dispatcher support.
|
||||
5. Extend existing facade/import-boundary checks as needed: all new public types
|
||||
belong to core, public signatures contain no Cobra/pflag/internal types,
|
||||
backend imports remain internal, and optional dependencies remain optional.
|
||||
6. Remove obsolete production helpers only after their responsibilities are
|
||||
accounted for. Do not retain parallel delivery paths for historical tests.
|
||||
|
||||
Validation: the suite should now build as a whole using the local three-module
|
||||
workspace. Focused reporter race testing is justified by the selected concurrent
|
||||
reporter contract; it does not establish a new permanent repository-wide gate.
|
||||
|
||||
## Stage 19: Update canonical documentation and compatibility guidance
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Update public Go declarations/GoDoc for exact reporter, outcome, provider,
|
||||
lifecycle, cause, and presentation-observation contracts. Describe callback
|
||||
writer scope and the selected non-reentrant callback boundary.
|
||||
2. Update [CLI reference](../cli.md) with the implemented mode/progress policy,
|
||||
flag placement and aliases, prefixes/channels, quiet help/version, usage
|
||||
guidance, and presentation-failure status behavior. Keep full operator
|
||||
definitions here rather than duplicating them in consumer prose.
|
||||
3. Update [consumer guide](../consumers/guide.md), [README](../../README.md),
|
||||
integration package documentation, and [developer guide](../development.md)
|
||||
as affected. Link to maintained examples; explain migration from raw
|
||||
invocation streams, error-first constructors, outcome diagnostics, terminal
|
||||
provider diagnostics, and old delivery fields.
|
||||
4. Update [internal overview](../internal/overview.md) with implemented ownership,
|
||||
parse occurrence flow, visibility selection, and finalization. Describe
|
||||
synchronization as implementation mechanics without expanding contracts.
|
||||
5. Update the unpublished [core v0.3.0 note](../releases/v0.3.0.md) with reporting
|
||||
scope and the intentional API/CLI compatibility impact, including newly
|
||||
reserved flag names. Preserve published historical notes and tags. Integration
|
||||
release-version selection and publication remain separate release preparation;
|
||||
do not invent release versions or edit historical integration notes.
|
||||
6. Mark feature implementation status accurately in the roadmap. Preserve the
|
||||
accepted ADRs and deferred work; do not create new architectural decisions
|
||||
for settled API details or retire the planning record during implementation.
|
||||
|
||||
Validation: review prose against implemented behavior, check local links and
|
||||
fragments, and run the Markdown whitespace checks from the developer guide.
|
||||
Current contract documentation must no longer present the removed APIs as valid.
|
||||
|
||||
## Stage 20: Validate the complete end state and finish
|
||||
|
||||
Status: pending.
|
||||
|
||||
1. Format changed Go files with `gofmt`; review the complete diff for unintended
|
||||
behavior changes, unselected restrictions, compatibility machinery, public
|
||||
backend leakage, or duplicate presentation paths.
|
||||
2. Preserve the existing ignored local `go.work`. Ensure it includes core,
|
||||
ckconfig, and ckprompt using the developer guide procedure. Keep unpublished
|
||||
sibling code under local workspace resolution. Do not commit workspace files,
|
||||
fabricate dependency sums, or change dependency versions solely to make an
|
||||
unreleased core API resolve through published versions.
|
||||
3. Run the ordinary suites for all three modules with `GOTOOLCHAIN=local`, using
|
||||
the workspace for integration development. The commands below are separate
|
||||
executions with the indicated working directories:
|
||||
|
||||
| Working directory | Command |
|
||||
| --- | --- |
|
||||
| Repository root | `GOTOOLCHAIN=local go test ./...` |
|
||||
| `integrations/ckconfig` | `GOTOOLCHAIN=local go test ./...` |
|
||||
| `integrations/ckprompt` | `GOTOOLCHAIN=local go test ./...` |
|
||||
| Repository root | `GOWORK=off GOTOOLCHAIN=local go test ./...` |
|
||||
|
||||
4. Run focused core reporter tests with the race detector, choosing `-run` to
|
||||
match the tests created during the sprint. Exercise maintained example
|
||||
commands covering core result/messaging, quiet help/version, scoped config
|
||||
YAML, aliases, and offline PromptKit report-plus-failure presentation.
|
||||
5. Treat workspace-based integration validation accurately: it validates this
|
||||
sprint's local modules. Independent integration dependency graphs are updated
|
||||
and validated during release preparation after their new dependencies are
|
||||
published, following the existing core → ckconfig → ckprompt release order.
|
||||
No release-tool publication exercise, remote push, or new toolchain/dependency
|
||||
upgrade is part of this feature validation.
|
||||
6. Check that every selected roadmap behavior is implemented or has a clearly
|
||||
identified blocker. Resolve sprint defects before declaring completion.
|
||||
Keep incidental debug wording, concurrent scheduling order, and private file
|
||||
layout out of contractual assertions.
|
||||
7. Review staged/untracked contents, local links, and `git diff --check` plus
|
||||
`git diff --cached --check`. Finish with focused local commits and report
|
||||
validation results, any genuine limitations, and worktree status. Do not
|
||||
declare a release or remove the roadmap/plan automatically.
|
||||
|
||||
## Completion criteria
|
||||
|
||||
The sprint is complete when the selected public API replaces the old paths;
|
||||
normal parsing supplies reporting selection in every context; one reporter owns
|
||||
each invocation's presentation and finalization; core and optional integrations
|
||||
share that policy; native upstream evidence remains authoritative; maintained
|
||||
examples and current documentation use the implemented API; and complete local
|
||||
validation succeeds. No additional product decisions are required for this plan.
|
||||
@@ -13,6 +13,8 @@ below are also selected. Architectural preparation is complete:
|
||||
[ADR 0014](../adr/0014-invocation-reporting.md) is accepted, and the
|
||||
[architecture policy](../policy/architecture.md) is aligned. Implementation has
|
||||
not started; implementation, validation, and maintained consumer examples remain.
|
||||
The [implementation plan](implementation.md) owns stage order and execution
|
||||
instructions.
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -850,85 +852,30 @@ Debug output follows the same upstream disclosure and safe-rendering contracts.
|
||||
Enabling debug does not authorize secret disclosure or bypass owning-library
|
||||
rules.
|
||||
|
||||
## Work needed
|
||||
## Delivery scope
|
||||
|
||||
1. Specify the selected behavior in examples covering ordinary application output,
|
||||
immediate and deferred diagnostics, failure after partial output, help and
|
||||
version, and integration diagnostics in every mode. Include applications that
|
||||
emit no Progress messages and the distinction between Info and Progress.
|
||||
Cover silent recovery, an explicit Warning with or without a Go error, and a
|
||||
terminal failure with an explicit explanation and no Go error cause.
|
||||
Include simple and structured failure construction without early emission,
|
||||
optional cause transport independent of operator text, and an integration
|
||||
returning both a substantive report and a failure. Include provider-returned
|
||||
independent warnings and terminal context, unexplained failures receiving the
|
||||
fallback, and rendering helpers using only the supplied callback writer.
|
||||
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. Implement the selected unified reporting API and flag contracts, including
|
||||
interactions with command and flag aliases, following OD-1 through OD-4 above.
|
||||
Replace split handler submission paths and adapt core and integration callers.
|
||||
Account for flag collisions and document changed public contracts.
|
||||
4. Implement the selected behavior across core and the integrations. Preserve
|
||||
upstream rendering and semantics while applying the chosen visibility policy.
|
||||
Adapt provider-returned `Acquired[T]`, `Diagnostic`, and `Severity` contracts
|
||||
to independent nonterminal messages and separate terminal explanations.
|
||||
Replace whole-batch severity promotion with deliberate separation of failure
|
||||
context and unrelated messages. Providers remain independent of the reporter.
|
||||
5. Verify classification, flag selection, suppression, terminal explanations,
|
||||
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. Cover explicit explanatory
|
||||
context in quiet mode, independent warnings in mixed batches, already-labelled
|
||||
native content, and distinct submissions with identical text. Verify the end
|
||||
of normal reporting after terminal error presentation, including deferred
|
||||
and late writes under the selected OD-4 behavior. Cover immediate and deferred
|
||||
ordering on success and failure, handler cleanup, automatic finalization,
|
||||
flushing ordinary buffers before terminal delivery, handler-completion debug
|
||||
placement, and ownership of caller-supplied writers. Verify concurrent reporter
|
||||
calls protect shared state and keep individual messages together, without
|
||||
requiring a predetermined order among concurrent submissions. Verify ignored
|
||||
immediate write errors and deferred delivery failures follow the outcome table
|
||||
above, original explanations and causes are retained, and failed destinations
|
||||
receive no further writes. Cover diagnostic-destination failure without
|
||||
fallback into substantive output, quiet-mode rendering failures, and
|
||||
suppression without destination writes or incomplete-delivery status.
|
||||
Distinguish renderer failures from destination failures, including callbacks
|
||||
that fail without writing and continued terminal delivery through a healthy
|
||||
diagnostic destination. Cover usage failure becoming operational failure when
|
||||
presentation fails, domain classification and non-zero status preservation,
|
||||
and zero domain status becoming `1`. Verify all category destinations and
|
||||
usage guidance under quiet mode.
|
||||
Verify the selected API's empty-heading native rendering, ordered details,
|
||||
deferred submission errors, replacement by `WithExplanation`, and delivery
|
||||
states for each destination. Check bounded first-error observations, rendering
|
||||
through `RenderOutput`, and `ErrReporterClosed` for retained handles in quiet mode.
|
||||
Verify `WithCause` preserves classification, status, and explanation, and
|
||||
`WithExplanation` preserves the cause. Check cause identity through outcome
|
||||
processing and subsequent presentation failures, including wrapped errors
|
||||
inspected with `errors.Is` and `errors.As`. Verify causes alone do not produce
|
||||
messages or change statuses or visibility.
|
||||
Verify provider-returned data remains unpresented until submitted by the
|
||||
integration, including data returned alongside an error. Cover mixed batches
|
||||
where terminal context remains visible in quiet mode and unrelated warnings
|
||||
remain suppressed. Verify generic fallback presentation and retention for
|
||||
failed outcomes with no message or non-nil detail renderer, with and without
|
||||
a cause. Check unchanged classifications, statuses, and causes when fallback
|
||||
delivery succeeds, and existing presentation-failure rules when it fails.
|
||||
Cover native details with an empty heading, including a renderer that writes
|
||||
no bytes, without adding a fallback or replaying callbacks to inspect content.
|
||||
Exercise callback helpers using the supplied writer, messages submitted before
|
||||
and after rendering, and ordinary concurrent submissions serialized around a
|
||||
complete rendering operation. Document the callback boundary without requiring
|
||||
runtime detection of recursive reporter use.
|
||||
6. Update GoDoc, the CLI reference, consumer guidance, and release documentation
|
||||
when implemented. Exact reporting APIs and flag syntax remain API/CLI
|
||||
contracts.
|
||||
The completed feature includes the selected reporter and outcome API, ordered
|
||||
mode/progress selection through normal parsing, shared core presentation, and
|
||||
both optional integration migrations. Passive provider diagnostics distinguish
|
||||
independent messages from terminal explanations while preserving native evidence
|
||||
and rendering. Existing command behavior remains unchanged outside the selected
|
||||
reporting policy.
|
||||
|
||||
Maintained consumers demonstrate ordinary output, immediate/deferred messages,
|
||||
silent recovery, explicit warnings, failure after partial output, optional cause
|
||||
transport, and structured terminal explanations. Integration consumers include
|
||||
native diagnostic context and useful reports returned alongside failures.
|
||||
|
||||
Behavioral coverage establishes CommandKit-owned parsing, visibility, ordering,
|
||||
concurrent reporter coordination, closure, presentation observations, and failure
|
||||
handling. It preserves existing alias, input/state, discovery, native-report,
|
||||
and upstream-adapter protections without testing upstream domain correctness.
|
||||
GoDoc, CLI documentation, consumer guidance, internal documentation, and release
|
||||
notes describe the implemented boundary under their canonical ownership.
|
||||
|
||||
The [implementation plan](implementation.md) defines the concrete migration
|
||||
steps, focused validation, and completion criteria. This roadmap defines the
|
||||
target behavior and selected policy choices.
|
||||
|
||||
## Architectural preparation completed
|
||||
|
||||
@@ -939,5 +886,6 @@ rules.
|
||||
ownership model, including application ownership of domain-specific error
|
||||
decisions and scope for useful shared error helpers.
|
||||
|
||||
OD-1 through OD-4 and the consumer API signatures are selected. Turn the target-API
|
||||
examples into maintained, executable consumers as implementation proceeds.
|
||||
OD-1 through OD-4 and the consumer API signatures are selected. The target end
|
||||
state includes maintained, executable consumers using those APIs; the
|
||||
[implementation plan](implementation.md) owns their delivery sequence.
|
||||
|
||||
Reference in New Issue
Block a user