Files
commandkit/docs/roadmap/implementation.md

771 lines
44 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Invocation reporting implementation plan
Status: Stages 1–15 complete. Stage 16 is next.
## 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: complete.
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: complete.
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: complete.
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: complete.
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: complete.
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.
Focused metadata and Cobra adapter tests pass. Root-package registration and
alias tests are included, but their execution is deferred until the planned API
migration restores root-package buildability.
## Stage 6: Preserve occurrence order through the normal parser
Status: complete.
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.
Focused internal package suites pass. Root reducer tests are included, but their
execution is deferred until the planned API migration restores root-package
buildability.
## Stage 7: Connect invocation execution to one reporter
Status: complete.
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.
The invocation now owns one reporter, applies ordered reporting selection before
preparation and handler execution, and finalizes normal outcomes through the
reporter. Focused internal suites pass. Root-package execution remains blocked
by the planned help/version migration and remaining legacy test callers; the
root test command was run and its compile errors are recorded for those later
steps. Focused invocation coverage has been added for reporter freshness,
selection, quiet usage guidance, early errors, and ignored output failures.
## Stage 8: Migrate help and version presentation
Status: complete.
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.
Help and version reports now render through the invocation reporter, including
quiet-mode rendering and destination-failure accounting. Tests cover quiet
success, canonical and alias help, alias-only discovery, invalid requests, and
destination failures. The internal suites pass; root-package execution remains
deferred because the existing external test package still references APIs
scheduled for the later suite reconciliation.
## Stage 9: Add core debug events
Status: complete.
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.
Routing, reporting-mode selection, and handler-completion events now use shared
Debug reporting. Early events are submitted after mode selection, and completion
is submitted after deferred messages. Focused tests cover alias identity,
selection order, quiet suppression, completion ordering, no-handler behavior,
cause privacy, and debug delivery failure. Internal suites pass; execution of
root tests remains deferred until the legacy external callers are reconciled.
## Stage 10: Separate ConfigKit provider messages and explanations
Status: complete.
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.
The ConfigKit adapter now carries independent warnings and terminal native
records separately, preserves partial values and wrapped errors, and snapshots
native writer inputs. Focused tests cover mixed records, source and comparison
side context, related locations, partial values, error identity, and messages
retained through cancellation. The ckconfig suite cannot run yet because
`diff.go`, `explain.go`, and `family.go` still use APIs scheduled for later
migration; Stage 20 will validate the assembled modules.
## Stage 11: Migrate configuration show and validate
Status: complete.
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.
Configuration show and validate now submit provider messages through the shared
reporter and render results through managed output. Tests retain acquisition
ordering, shared state, YAML framing, cancellation with partial validation
output, and cover warning visibility, terminal context, quiet rendering, and
destination failures through `Presentation`. The ckconfig tests remain
unrunnable because `sources.go`, `explain.go`, `diff.go`, and family wiring and
tests still reference APIs scheduled for later migrations; Stage 20 will run the
assembled suites.
## Stage 12: Migrate configuration sources, explain, and diff
Status: complete.
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.
Configuration sources, explanation, diff, and scope inventory now submit
provider messages through the shared reporter and render through managed output.
Native explanation rendering retains already-written partial output, while
renderer and destination failures are recorded in `Presentation` independently
of operation causes. Focused ckconfig package tests pass, including comparison
preflight, source evidence, safe reports, native forwarding, warning/context
ordering, quiet rendering, and result/diagnostic destination failures. The full
ckconfig module command still fails to compile `examples/simple`, which uses the
old invocation API and is scheduled for migration in Stage 17.
## Stage 13: Migrate PromptKit acquisition adapters
Status: complete.
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.
PromptKit engine loading now separates independent warning batches from native
terminal records and carries both through catalogs, inspection, requirements,
ConfigScope comparison, concrete request validation, and smoke acquisition.
Native rendering retains scope/side headings, source legends, and diagnostic
locations; original errors and reports returned with errors remain available.
Offline adapter tests cover mixed record separation, writer propagation,
comparison-side context, error identity, and existing request lifetimes. The
ckprompt suite cannot execute yet: compiler diagnostics identify legacy
reporting calls in `command.go`, `smoke_command.go`, and their tests, which are
scheduled for Stages 14 and 15. No compile errors were reported in the migrated
adapter files; Stage 20 will run the assembled suite.
## Stage 14: Migrate PromptKit listing and inspection commands
Status: complete.
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.
PromptKit catalog listing, definition inspection, and requirements inspection
now submit provider messages through the reporter and render complete reports
inside managed output. Acquisition failures use native terminal context when
available and preserve the original cause. Tests cover independent warning and
terminal-context delivery, successful ordinary/quiet/verbose/debug execution,
quiet encoding failure, cancellation, and result delivery observations. The
ckprompt suite cannot run yet because `validation_command.go` and
`smoke_command.go` still use the legacy reporting API scheduled for Stage 15;
Stage 20 will validate the assembled module.
## Stage 15: Migrate request validation and smoke commands
Status: complete.
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.
Concrete request validation and PromptKit smoke commands now submit passive
messages through the reporter and render confirmation, native, and aggregate
reports inside managed output. Smoke reports remain available alongside
operation failures, with native explanations and causes retained separately;
aggregate collection order and shared input/state lifetimes remain covered.
`GOTOOLCHAIN=local go test -count=1 .` passes in `integrations/ckprompt`. The
module-wide `go test ./...` reaches and passes that package but cannot compile
`examples/composed`, whose legacy API callers are scheduled for Stage 17.
## 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.