diff --git a/docs/adr/0006-invocation-reporting.md b/docs/adr/0006-invocation-reporting.md index 109f6dc..9c462aa 100644 --- a/docs/adr/0006-invocation-reporting.md +++ b/docs/adr/0006-invocation-reporting.md @@ -3,9 +3,8 @@ ## Status Accepted. -The structured-report formatting extension is accepted but not yet implemented; -the [adoption roadmap](../roadmap/promptkit-v0.20.0.md#shared-core-report-output-prerequisite) -tracks that work. +The structured-report formatting extension is implemented; its adoption record +is preserved in [Git history](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/2f43f78f76439f5d11ef313cd379bec036543504/docs/roadmap/promptkit-v0.20.0.md#shared-core-report-output-prerequisite). ## Date diff --git a/docs/development.md b/docs/development.md index e737a53..c27179e 100644 --- a/docs/development.md +++ b/docs/development.md @@ -72,7 +72,8 @@ Read all applicable rows for cross-cutting work. Go declarations and GoDoc own current exported contracts; the CLI reference owns operator behavior. The [maintainer release procedure](release.md) owns current release operations. Completed roadmaps and implementation evidence remain available in Git history, -including [PromptKit v0.18.0 adoption and implementation](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/540e2359d66d604a563df0be1c9fc961588f5b9c/docs/roadmap), +including [shared reporting and PromptKit v0.20.0 implementation](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/2f43f78f76439f5d11ef313cd379bec036543504/docs/roadmap), +[PromptKit v0.18.0 adoption and implementation](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/540e2359d66d604a563df0be1c9fc961588f5b9c/docs/roadmap), [ConfigKit adoption, reporting, release-tooling, and remediation records](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/260256d722f52bc947103d078cb67a129f4cc9f1/docs/roadmap), [application-owned alias planning, implementation, and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/f42aefe02d84e154855ac922173e6f367180929f/docs/roadmap) and [PromptKit requirements implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/40499a43608bf60d1104cd8ee24caf18ac0e9e66/docs/roadmap). diff --git a/docs/policy/architecture.md b/docs/policy/architecture.md index e92a1a7..35fa71e 100644 --- a/docs/policy/architecture.md +++ b/docs/policy/architecture.md @@ -161,8 +161,8 @@ and deferred messages. Core owns shared visibility, formatting, delivery, and finalization. Applications and integrations choose their report content and messages; callers choose the destinations. [ADR 0006](../adr/0006-invocation-reporting.md) records this reporting and outcome -ownership model. Its accepted structured-report extension remains planned in the -[adoption roadmap](../roadmap/promptkit-v0.20.0.md#shared-core-report-output-prerequisite). +ownership model. The [CLI reference](../cli.md#reporting) describes the +implemented structured-report behavior. For that shared report handoff, core owns format selection, serialization, template execution, and delivery. Applications and integrations select logical diff --git a/docs/roadmap/future.md b/docs/roadmap/future.md index 90d0f62..148e7a6 100644 --- a/docs/roadmap/future.md +++ b/docs/roadmap/future.md @@ -5,12 +5,14 @@ No delivery dates are selected here. ## Purpose and authority -Earlier completed roadmaps, implementation plans, and review findings have been retired. +Completed roadmaps, implementation plans, and review findings have been retired. This document preserves unfinished work and unselected ideas under the [release policy](../policy/release.md#release-documentation-and-preparation). The completed PromptKit v0.18.0 adoption roadmap and implementation plan remain available in the [PromptKit retirement snapshot](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/540e2359d66d604a563df0be1c9fc961588f5b9c/docs/roadmap). +The completed PromptKit v0.20.0 and shared reporting implementation is recorded +in its [retirement snapshot](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/2f43f78f76439f5d11ef313cd379bec036543504/docs/roadmap). The completed ConfigKit adoption, reporting, dependency alignment, release-tooling, and remediation records remain available at the [retirement snapshot](https://forge.maximumdirect.net/base-layer/commandkit/src/commit/260256d722f52bc947103d078cb67a129f4cc9f1/docs/roadmap). diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md deleted file mode 100644 index 9d2dd66..0000000 --- a/docs/roadmap/implementation.md +++ /dev/null @@ -1,1045 +0,0 @@ -# Shared reporting and PromptKit v0.20.0 implementation plan - -Status: implementation complete; Stages 1–26 complete. - -## Scope, authority, and execution - -Implement the accepted target in the [feature roadmap](promptkit-v0.20.0.md). -That document owns operator intent, selected behavior, OD-1 through OD-11, and -exclusions. This plan owns the transition, API design choices, stage order, and -verification. Read [development](../development.md), the -[agent policy](../policy/agents.md), and applicable policies before each stage. -Use [architecture](../policy/architecture.md), [testing](../policy/testing.md), -[documentation](../policy/documentation.md), [OSS](../policy/oss.md), and -[release](../policy/release.md) for their respective work. The -[ADRs](../adr/README.md) explain the accepted architecture. - -Execute the numbered stages in order. Each stage is sized for one focused Luna -implementation prompt. This is one end-to-end sprint: intermediate stages may -fail to compile while dependent callers are being converted. Do not introduce -compatibility layers or temporary public APIs to keep those stages green. -Carry relevant tests and GoDoc with their owning change; defer broad suites -until their dependencies exist. Record completed stages and actual validation -here, commit completed reviewable units under repository policy, and preserve -unrelated work. A stage boundary is not a publication or compatibility boundary. - -The inspected baseline is `cb7e05284c554f0da170dc17a0e2e3eac2aed0bc`. -It has core v0.3.0 requirements in both integrations, ckconfig v0.3.0 in -ckprompt, PromptKit v0.18.0, and ConfigKit v1.1.0. The feature roadmap records -the pinned PromptKit v0.20.0 and ConfigKit v1.1.0 evidence. Use those released -sources only. Do not follow unreleased upstream work or change sibling repos. - -Use Go 1.27.0 on PATH as described in the [release procedure](../release.md). -Preserve the ignored aligned `go.work`, `go.work.sum`, and local credentials. -Never inspect token contents. Do not commit workspace files, local replacements, -or invented checksums. Core retains its Go 1.26.0 consumer minimum; integrations -retain 1.27.0. During joint development use the aligned workspace. Stages 24–26 -explicitly handle released requirements and independent builds. - -Public names below select a concrete design, not existing API. Private file -splits and helper names may follow idiomatic implementation needs. If a concrete -API adjustment is necessary, preserve the selected behavior, explain the reason, -and update dependent stages; do not reopen settled scope or silently add policy. -No arbitrary deep-copy, concurrent-dispatch, exact-byte output, transactional -writer, or upstream-domain correctness guarantee is added by this plan. - -## Coverage and checkpoints - -| Target owner in the feature roadmap | Implementing stages | -| --- | --- | -| Shared reporting, safe conversion, universal formats, and output inventory | 1–4, 7–9, 23 | -| Public CLI JSON and ordered typed bindings | 5–6 | -| Released adoption, resource reports, native errors, and smoke evidence | 8–9 | -| OD-1 prepared preview and OD-2 controls/input/aliases | 10–11, 13 | -| OD-3 namespace defaults and applicability | 12 | -| OD-4 metadata discovery and OD-8 focused inspection | 14, 17–18 | -| OD-5 detailed diff and OD-10 assertion outcomes | 19 | -| OD-6 failure evidence and aggregate validation | 14, 18, 20 | -| OD-9 independent comparison and OD-11 overrides | 15–16 | -| Maintained consumers and canonical contracts | 21–23 | -| OD-7 releases, real dependency alignment, and final validation | 24–26 | - -## Stage 1: Shared report representation and safe YAML conversion - -**Complete.** JSON normalization and safe YAML conversion are implemented. -Focused conversion tests and the root workspace suite (`GOTOOLCHAIN=local go -test ./...` with Go 1.27.0) passed. - -Start in the root package beside [reporter.go](../../reporter.go). Add private -report normalization using `encoding/json`: marshal the original report value, -then decode with `UseNumber` into maps, sequences, scalars, null, and -`json.Number`. Honor JSON tags, omissions, and custom serialization once for -all core-serialized formats. Keep numeric tokens intact instead of routing them -through float64. Strings remain ordinary strings. Unsupported serialization is -an observable error; no stringification fallback. - -Add public `DecodeYAMLReport(io.Reader) (any, error)` for one safe inspection -YAML document. Use the existing YAML v4 dependency and a private node walk to -produce ordinary JSON-compatible values. Preserve scalar types, presence, -null/empty distinctions, sequence order, and numeric value. Standard -`json.Number` may retain JSON numeric tokens without imposing Stage 5's CLI -number policy. Convert supported YAML numeric notation faithfully; report an -unrepresentable value rather than rounding or silently treating it as text. -The helper is explicitly for the restricted inspection value model, not a -lossless YAML editor. Reject unsupported meanings, such as a non-string mapping -key or multiple logical documents, with a conversion error. Do not parse report -strings heuristically or read application configuration structs or source files. - -Build one private conversion from the normalized representation to YAML nodes, -including numeric nodes rather than quoted numeric strings. This representation -also feeds JSON and automatic shape selection. No public document tree or new -serialization tags. - -Verify JSON field/custom-serialization behavior and meaningful scalar, number, -presence, empty-container, and redaction preservation with focused core tests. -Include large integers and strings resembling numbers or booleans. Tests compare -logical values, not YAML quoting or mapping order. - -## Stage 2: Writer rendering and standard text templates - -**Complete.** Writer rendering and reusable text templates are implemented. -Focused rendering tests and the root workspace suite (`GOTOOLCHAIN=local go -test ./...` with Go 1.27.0) passed. - -Add these public root-package contracts: - -- `Format` with `FormatText`, `FormatYAML`, and `FormatJSON`; its zero value means - automatic selection for direct writer use. -- `Report{Value any; TextTemplate *template.Template}`. -- `ParseTextTemplate(name, source string, funcs template.FuncMap) - (*template.Template, error)`, using standard `text/template`; nil funcs is valid. -- `RenderReport(io.Writer, Report, Format) error`. - -Use one implementation for all formats. Follow the feature roadmap's -[selection table](promptkit-v0.20.0.md#agreed-universal-and-automatic-format-selection): -explicit format first, otherwise a supplied template selects text, otherwise -select by the normalized outer shape. Untemplated strings, numbers, booleans, -and nonempty string lists use plain text; structured values, empty collections, -and null use YAML. Explicit text for that second group uses the same YAML -renderer. For scalar text emit a terminating newline; for string lists emit one -item per line. Execute templated text as supplied without another formatting pass. -Use conventional readable YAML and JSON encoding; whitespace and map order are -not additional contracts. An unknown nonzero writer Format returns an error -rather than selecting a fallback. - -Templates receive the original Go value. Templated text does not marshal JSON -first; explicit YAML/JSON does not execute the template. Template preparation, -execution, unsupported serialization, and writer errors remain observable, with -no renderer fallback on failure. Callers can prepare reusable templates during -assembly and attach preparation errors through existing declaration-error APIs. -Use normal template functions initially; no helper framework or public template -value model. Caller-supplied template objects retain ordinary Go ownership. - -Verify all automatic shapes, explicit precedence, original-value template access, -JSON-ignored fields in templates, unsupported JSON values, template errors, -large-number YAML/JSON fidelity, and short/error writers. Keep expectations -semantic except where the selected text behavior itself matters. - -## Stage 3: Reporter handoff through the existing lifecycle - -**Complete.** Reporter handoff uses the existing delivery lifecycle. Focused -reporter tests and the root workspace suite (`GOTOOLCHAIN=local go test ./...` -with Go 1.27.0) passed. - -Add `(*Reporter).Report(Report) error`. Delegate to Stage 2 through the existing -`RenderOutput` coordination and destination writer. Store the invocation format -selection in reporting state; do not create another reporter or delivery state. -Keep existing raw writes and `RenderOutput` available as deliberate raw paths. - -Preserve quiet-mode rendering through discard, closed-reporter handling, -separate presentation evidence, and existing final outcome precedence. Do not -add a context-cancellation gate to `Report`: handlers decide whether to submit -already-acquired evidence. Do not close or flush caller writers. Avoid recursive -report submission from inside a rendering callback. - -Exercise rendering errors under quiet mode, a successful operation with delivery -failure, a nonzero domain outcome with delivery failure, supported cause identity, -and submission of acquired content after cancellation. Reuse existing reporter -and outcome coverage where unchanged. Document the public handoff and raw-output -boundary in GoDoc. - -## Stage 4: Universal format input, core version, and a core consumer - -**Complete.** Core format selection, version reporting, and a maintained core -consumer use the shared report path. Focused parser, routing, completion, and -reporting tests and the root workspace suite (`GOTOOLCHAIN=local go test ./...` -with Go 1.27.0) passed. Integration migrations remain in later stages. - -Extend neutral core flag metadata and parser selection in -[metadata.go](../../internal/commandmeta/metadata.go), -[parser.go](../../parser.go), and the internal Cobra adapter. Add core-owned -`--format` with `text`, `yaml`, and `json` completion. Omission means automatic; -explicit empty or unknown formats are usage errors before input factories, -acquisition, or handlers. Validate supplied occurrences using normal singleton -conversion behavior; the last valid supplied choice selects the format. Preserve -entered spellings, consumed values, `--`, reporting-mode ordering, and fresh -invocation state. Do not treat the value-taking flag as a boolean when generating -completion or reducing core flag occurrences. - -Use existing core-flag placement and alias mechanisms. Reserve the long name -`format` at installation, with no built-in short spelling. A local binding or -conflicting alias source produces the existing installation collision error; -a deliberate alias to core `--format`, such as `--fmt`, remains supported. -Remove the version command's local format binding and switch its report to -`Report` plus an ordinary version text template. Do not encode help, usage, -completion protocol output, or diagnostic messages as reports. - -Convert one maintained [core consumer](../../examples/core) command to a data -handoff and optional template, with no format switch. Exercise core/application -reports in all three formats, unknown formats before domain work, format aliases, -metadata/help without acquisition, reservation collisions, and repeated -invocations. Update the core CLI and consumer reporting sections with the landed -boundary; later documentation stages complete the integration inventory. - -## Stage 5: Public CLI JSON parsing - -**Complete.** CLI JSON parsing and numeric conversion are implemented. Focused -boundary tests and the root workspace suite (`GOTOOLCHAIN=local go test ./...` -with Go 1.27.0) passed. - -Add `ParseCLIJSON(string) (any, error)` in core. Decode exactly one JSON value -with `UseNumber`, require completion of that value, and recursively convert -numbers under [OD-2](promptkit-v0.20.0.md#od-2-request-controls-and-provider-parameter-grammar). -Integer syntax becomes int64, or uint64 for representable nonnegative overflow; -decimal/exponent syntax becomes float64. Return syntax and numeric range errors; -accept ordinary float approximation. Preserve nested arrays, objects, null, -booleans, and strings. Keep conversion and its required policy/rationale comments -in one private CLI helper. This parser is separate from report normalization. - -Test nested values, signed/unsigned integer boundaries, out-of-range values, -decimal and exponent syntax, floating range failures, trailing JSON, and ordinary -float approximation. Do not add arbitrary-precision types or a public numeric -conversion API. Each integration will enforce its flag's outer shape. - -## Stage 6: Ordered typed occurrences and reusable binding identity - -**Complete.** Ordered typed occurrences and independently renamed bindings are -implemented, including captured subset replay. Focused binding tests and the -root workspace suite (`GOTOOLCHAIN=local go test ./...` with Go 1.27.0) passed. - -Extend [binding.go](../../binding.go), [flag_values.go](../../flag_values.go), -and the neutral preparation path to retain ordinal positions from existing -`FlagOccurrences`. Add: - -- `OccurrenceFlag[I,V](FlagMeta, func(string) (V,error), - func(*I, Supplied[V])) Flag[I]`: repeatable, converted once per supplied - occurrence, no fallback occurrences; invokes its setter once per occurrence. -- `RenameFlag[I](Flag[I], name string) Flag[I]`: independent binding identity, - same parser/setter/default/required/completion behavior, replacement long name, - and no inherited short spelling. Normal declaration validation still applies. - -Apply participating occurrence bindings in actual command-line order across -canonical spellings and aliases. Ordinary bindings keep their existing grouped -semantics. During input construction apply ordinary flag values, then ordered -occurrences, then operands, before `CheckInput`. The relative ordering contract -is needed among participating occurrence bindings, not between arbitrary caller -side effects. All conversion failures still occur before input construction. - -Extend private prepared values with typed occurrence closures and ordinals. -`CaptureFlags` retains those records against original binding identities; -`FlagValues.ApplyTo` checks the selected subset and required presence, then -replays only its participating records in order without parsing again. Repeated -applications retain independent core-owned parsed collections. Preserve existing -wiring-versus-usage classification; expose neither raw arguments nor backend -objects. `RenameFlag` must preserve ordered behavior when used on such a binding. - -Verify interleaved distinct flags and aliases, repeated names, explicit empty -values, omitted bindings, subset selection, conversion failure, required checks, -renamed handles, repeated application, and fresh invocations. Do not change the -ordinary `RepeatFlag` replacement semantics to simulate ordering. - -## Stage 7: Migrate existing ckconfig reports to core - -**Complete.** Existing ckconfig reports use shared rendering, including safe -effective values and reached-scope validation aggregation. Focused integration -tests and the root and ckconfig workspace suites passed with Go 1.27.0 using -`GOTOOLCHAIN=local go test ./... ./integrations/ckconfig/...`. The ckprompt -migration remains in the following stages. - -Convert the existing `scopes`, `show`, `sources`, `explain`, `diff`, and concise -`validate` report paths in [ckconfig](../../integrations/ckconfig) to the public -handoff. Remove local format flags, validators, encoding switches, and encoders. -Give integration-owned projections JSON tags for their selected content; thin -path/location/snapshot projections remain appropriate. - -For effective display, capture native `WriteEffective` output, call -`DecodeYAMLReport`, and hand off that logical value without a text template. -For `--scope all`, acquire all requested views and complete required validation -before output; combine their safe values into one map keyed by scope ID, even -with one registered scope. Single-scope output is unwrapped. Retire document -markers and scope-comment framing; do not promise mapping order. An acquisition -failure prevents the combined display. Conversion/rendering failures use the -presentation path, including under quiet mode. - -Keep current content where the target does not change it. Use concise text -templates for scopes/source inventories and existing explanation summaries when -appropriate; default diff remains a structured mapping without a template. -For concise validation, collect reached-scope results before one submission; -stop acquisition on failure/cancellation and preserve its outcome. Stage 20 -extends that same aggregation with structured evidence rather than introducing -another validation delivery path. - -Verify universal formats, safe-value conversion, aggregate shape, selected -single-string output, provider failure before combined display, and separate -presentation failures. Replace obsolete native-byte/document-order assertions -and update current display/validation contracts and the corresponding testing -policy wording as behavior changes. Do not add domain comparison tests. - -## Stage 8: Adopt PromptKit v0.20.0 and native resource inspection - -**Complete.** ckprompt selects released PromptKit v0.20.0 at commit -`8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf` with verified module sums and -updated attribution. Native prompt, profile, and backend inspection tests, -including format, callback, error, and cancellation cases, passed with Go -1.27.0. Root and ckconfig workspace suites also passed. The full ckprompt suite -still encounters the remaining local format bindings scheduled for Stage 9; -those bindings are not part of the completed inspection migration. - -Update ckprompt's PromptKit requirement and authentic sums to v0.20.0; keep -ConfigKit v1.1.0 and existing Go minima. Review the released notices and update -[module attribution](../../integrations/ckprompt/docs/oss/attribution.md) and -applicable transitive notices. Do not fabricate future CommandKit dependency sums. - -Implement the [resource inspection target](promptkit-v0.20.0.md#resource-inspection). -Remove duplicated prompt/profile report structs and per-field formatters; pass -the native `PromptInspection` and `ProfileInspection` to core, without templates. -Add `BackendRequest{Selection ckconfig.Selection; ID string}` and an independently -optional `Suite.InspectBackend` callback returning -`commandkit.Acquired[*promptkit.BackendInspection]`. Wire `FromEngine` through -native `InspectBackend`, and install `show backend BACKEND_ID` when available. -Stage 12 adds the common namespace field to these requests. - -Use native JSON omission/presence and returned captured messages. Do not complete -profile settings, infer readiness, resolve credentials, or reconstruct provenance -in these commands. Preserve errors, including native backend-not-found identity, -acquisition diagnostics, cancellation, and presentation failures. Adapt only -fixtures and callers affected by the released API; retain legitimate collection -release/version evidence. - -Verify native handoff fidelity across all formats, independent callback absence, -no loading for help/completion, positional IDs, omitted versus explicit resource -fields, native errors, and cancellation. Assert adaptation against returned -native evidence rather than rechecking upstream inheritance or rendering. - -## Stage 9: Consolidate remaining ckprompt reports - -**Complete.** Requirements, catalogs, and smoke reports use shared rendering. -The root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0, -including smoke evidence, cancellation, quiet, and delivery-failure tests. - -Move requirements show/validate, all catalogs, and smoke reports onto core -rendering. Remove remaining local format bindings, allowlists, encoders, and -format-specific report paths. Preserve selected report content with JSON tags -and text templates where a concise text view already serves operators. Keep -smoke reports as structured values without a dedicated text template. - -Single smoke reports retain native returned evidence, even with an operation -error. `test all` submits one report containing its ordered reached test results; -stop under the existing operation/cancellation lifecycle and retain partial -results. Core does not aggregate tests. Do not drop an acquired report merely -because the context became canceled; do not fabricate a report when native -preparation returned none. Preserve authentication response-limit unknown facts, -preparation-error causes, and operational failures. Findings that are false, -unknown, unsupported, or incomplete do not independently change command status. - -Verify one JSON document for aggregation, partial report plus error, no-report -preparation errors, cancellation after evidence acquisition, quiet rendering, -and delivery failure without losing domain evidence. Use deterministic native -fixtures/test doubles rather than network probes. Update current report guidance -for the converted commands. - -## Stage 10: Reusable execution and resource flag collections - -**Complete.** Reusable request flag collections feed requirements discovery, -validation, and smoke requests; the next stage supplies ordered text/file -precedence and prepared-request preview. The root, ckconfig, and ckprompt -workspace suites passed with Go 1.27.0, including collection and builder tests. - -Implement CLI-specific collections in ckprompt using ordinary public core flags. -Use typed flag-set structs exposing named original `Flag[I]` handles and an -`All() []Flag[I]` convenience method; callers select subsets with ordinary slices. -Constructors take a destination accessor into the application's own input type. -This avoids a new core collection API, string-keyed value lookup, or enum-driven -request builder. - -Select these collection/value boundaries: - -- `ExecutionInput` holds native `*ExecutionTargetOverride` and `*int` - transient retries. `NewExecutionFlags` supplies the eleven execution controls - from OD-2 through named handles. Allocate the native override only when a - relevant value is supplied; retain pointer zero/empty values and upstream - scalar semantics. -- `ResourceInput` holds presence-aware prompt/profile/backend/session IDs. - `NewResourceFlags` exposes those handles independently. -- `PromptInputs` holds native variables and artifact-reference maps. - `NewPromptInputFlags` supplies variable/text/file handles; Stage 11 fills in - ordered text/file construction. No application-internal execution helper is - introduced. - -Use canonical names from the [OD-2 table](promptkit-v0.20.0.md#od-2-request-controls-and-provider-parameter-grammar). -Define each name, usage, and alias relationship once in ckprompt metadata reused -by Stage 13. Preserve existing scalar syntax and integer timeout units. -`--llm-extra-params` is a singleton object parsed by `ParseCLIJSON`; reject a -non-object through the usage path and forward an explicit empty object unchanged. -Leave upstream value validation and whole-map replacement to PromptKit. - -Use execution controls on validation, preview, and smoke. Profile selection is -applicable to all three; prompt selection remains positional for validation and -preview. Backend selection is for native smoke requests; ordinary RunRequest has -no backend-selection field. Session, variables, and prompt inputs apply only to -the request operations that consume them. Requirements show uses only its -profile/session/variable context. Resource inspection gets no execution flags. - -Retain authoritative application builders: seed the native request once, allow -a complete replacement, and never reapply flags afterward. Preserve nil versus -explicit retries and the different native ordinary/smoke defaults. Verify -collection use with an application-owned input, selected subsets, zero/empty -forwarding, JSON object parsing, and builder replacement at the boundary. - -## Stage 11: Ordered literal/file inputs and concrete preview - -**Complete.** Text and file inputs follow command-line occurrence order, and -prepared-request preview is independently installable. The root, ckconfig, and -ckprompt workspace suites passed with Go 1.27.0; focused tests cover request -forwarding, native results and errors, builder replacement, and no model calls. -Scoped aliases are verified with their installation in Stage 13. - -Use `OccurrenceFlag` for named text/file assignments. Split at the first `=`, -preserve literal empty text, construct native `Inline` or `File` references, and -assign into the same `PromptInputs.Inputs` map as occurrences are replayed. -The last occurrence per name wins across both forms. Use canonical flags and -aliases exactly as OD-2: `--input` now denotes literal text; file access uses -`--llm-input-file` or its later scoped alias. Do not infer files from text. -No prompt-input flags go onto smoke tests. - -Add `PreparationRequest` carrying selection and native RunRequest, an optional -`Suite.PrepareRequest` callback returning `Acquired[*promptkit.PreparedRun]`, and -`WithRequestPreparation` taking the same loader/builder pattern as -`WithRequestValidation`. Install `show prepared PROMPT_ID` independently of -validation/resource inspection. Forward one final built request to native -`Engine.Prepare` exactly once; do not call ValidateRequest first or retain a -prepared execution handle. Hand off native PreparedRun without a template. -Stage 12 extends the common request envelope with namespace selection. - -Reuse input/state preparation and diagnostics. Explain in command help that -preparation does resource I/O and reports rendered application content without -calling the model. No execution-success or public-disclosure guarantee. - -Verify alternating text/file occurrences, duplicate names, aliases after Stage 13, -empty literals, values containing `=`, fresh invocations, builder replacement, -preview callback independence, request/context forwarding, native result/error -identity, and no model invocation. Derive expected preview evidence from the -native result rather than asserting PromptKit's rendering algorithm. - -## Stage 12: Opt-in namespace composition - -**Complete.** Opt-in namespace defaults and applicable selectors reach custom -callbacks and native engine views. The root, ckconfig, and ckprompt workspace -suites passed with Go 1.27.0; focused tests cover default composition, clearing, -applicability, loader views, and native error identity. - -Add `WithNamespaces(suite, promptkit.Namespaces) Suite` and store explicit -application defaults in an optional suite field. Add `Namespaces -*promptkit.Namespaces` to applicable ckprompt request envelopes, including -preparation and smoke. Nil means leave the loader's view untouched. With the -option enabled, start with its declared defaults and replace only supplied CLI -fields, including explicit empty clearing; populate the final native value in -the operation request. Native adapters apply one `Engine.WithNamespaces` call -after loading and before the selected upstream operation. - -Implement only the flags in [OD-3's applicability table](promptkit-v0.20.0.md#od-3-namespace-flags-and-loader-defaults). -Keep catalog filters and global configuration inspection separate. `FromEngine` -callbacks and validation/preparation/smoke adapters consume request namespace -selection consistently; custom callbacks receive the selection without an extra -hidden loader. Builders retain authority over their native requests. Loaders -using the standard option leave view-default selection to the adapter; loaders -without it remain usable as before. - -Explain native requirements profile identity in help, including explicit short -profile selection versus the prompt's stored default reference. Do not rewrite -configured references or try to make discovery profile-independent. - -Verify defaults plus one override preserve unrelated defaults, explicit clearing, -qualified IDs, applicable flag availability, custom loader behavior without the -option, and native view/error forwarding. Test boundary equivalence, not native -namespace membership or requirements-analysis correctness. - -## Stage 13: Generated scoped aliases and complete-family installation - -**Complete.** `Declarations` generates aliases from each command's selected -bindings; `Command` remains canonical-only. The root, ckconfig, and ckprompt -workspace suites passed with Go 1.27.0, including alias routing, occurrence -order, optional commands, help, completion, and conflict checks. - -Add `Declarations(suite) []commandkit.Declaration`, assembling the canonical -family and generated exact-command `FlagAliasFor` rules. Retain `Command(suite)` -for canonical-only installation. Generate aliases from the selected flags and -shared metadata built in Stages 10–12, following OD-2/OD-3; do not keep a separate -command-by-flag matrix. Generate only for installed commands and applicable -bindings. No aliases are application-wide by default. - -Use the existing routing/installation boundary, original binding identities, -and conflict checks. Application-owned commands can install deliberate aliases -through the public core API. Do not add subtree scopes, wrapper commands, or a -new declaration-bundle type. Canonical-only help must not claim convenience -aliases that were never installed. - -Exercise convenient and canonical-only assembly, optional callback subsets, -command aliases with scoped flag aliases, unknown/inapplicable names, native -binding presence, mixed-alias occurrence order, and ordinary installation -conflicts. Metadata/help/completion remain independent of engine acquisition. - -## Stage 14: Metadata and failed-acquisition evidence facets - -**Complete.** Scope feature discovery and native metadata, findings, and -failed-load source snapshots are available to subsequent operation modes. -The root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0, -including wrapped failures and independent diagnostic delivery. - -Extend [ckconfig contracts](../../integrations/ckconfig/contracts.go) with -`Scope.Features ScopeFeatures`: `PathDiscovery`, `PathShow`, and `Overrides` -booleans. These describe optional modes within existing commands, not new -subcommands. Native adapters advertise the first two; overrides remain explicit -loader opt-in in Stage 16. Retain existing `Operations` and the six-command -family. Capture features with the suite, check requested mode availability -before acquisition, and include supported feature names in scope discovery/help. -A declared mode missing its required acquired facet is an operational provider -wiring error, not an empty successful report. Detailed validation itself remains -available on validation scopes and can report unavailable native findings. - -Add `View.Metadata *configkit.Metadata` and `View.Findings *Findings`, with -`Findings{Records []configkit.Diagnostic; Messages []commandkit.Diagnostic}`. -Nil findings means unavailable; a nonnil empty record set means acquired but -empty. Existing `View.Sources` supplies optional inventory, including after an -error. Keep metadata as a deliberate upstream public value dependency; no -parallel metadata engine or generic diagnostic framework. - -Put native-generated ordinary warning presentations in `Findings.Messages`, -with their known association to the native record set. Keep unrelated application -messages in `Acquired.Diagnostics`. Ordinary handlers queue both groups; -detailed validation reports native records and queues only unrelated messages, -so filtering does not produce duplicate ordinary warnings. Keep the existing -terminal explanation, even when it describes a finding. Do not deduplicate by -message text or discard caller messages with no known relationship. - -Update `FromConfigKit` and `ckprompt.ConfigScope`: successful loads expose native -safe writers, sources, metadata, and findings. A matched `*configkit.LoadError` -exposes its captured Sources/Diagnostics alongside the original error. Use that -error snapshot as the failure evidence rather than appending a duplicate result -inventory; do not expose effective configuration or metadata from a failed load. -Other failures may have no structured evidence. Keep unavailable distinct from -available-empty inventory via the optional source reader. Preserve error chains -and existing diagnostic severity/terminal ownership. Ordinary PromptKit loading -outside ConfigScope continues its normal diagnostic delivery. - -Update acquisition-report helpers to queue native presentations from their new -owner without changing unaffected operations. Test both native adapters, success, -matched/wrapped errors, empty versus unavailable evidence, no effective facet on -failure, independently supplied diagnostics, and metadata/help without loading. - -## Stage 15: Independent comparison selector inputs - -**Complete.** Comparison sides now capture and apply independently declared -selectors and configuration selections. `FlagValues.ApplySuppliedTo` was added -to core because ordinary captured replay also applies flag defaults; this keeps -each side's factory defaults intact while retaining required checks and ordered -occurrences. Root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0. - -Replace inheritance in [input.go](../../integrations/ckconfig/input.go). -Add `Selector.AgainstName string`; an empty name declares no right-side flag. -For a declared counterpart use Stage 6's `RenameFlag` to retain domain parsing -and setter behavior with a fresh identity and no copied short alias. Capture -left and right values into distinct `FlagValues[I]` stores. Validate name -collisions through normal assembly; do not auto-generate counterpart names. - -Prepare each side with a separate `NewInput`, applying only that side's bindings -and selection. Omitted fields preserve the factory's ordinary defaults and -unsupplied state. Remove `inheritComparisonSelection`; config and overlay -counterparts also start independently. No selector value or repeatable collection -is copied to the opposite side, including when that side is partly supplied. -Required checks apply to the applicable declared subset on its side. Complete -both input checks before one `NewState` and the existing pair provider call. -Command-wide scope/format/detail/assertion controls stay outside side inputs. -Equal selections still acquire both sides and compare. - -Verify OD-9's left-only/right-only/both/neither and partial-side cases, custom -repeated selectors, required inputs, supplied state, fresh invocation storage, -shared state, and checks before acquisition. Keep application factory objects -and caches application-owned; no arbitrary deep copying. Update selector GoDoc -and replace the canonical comparison inheritance description with the selected -model. Explicit-empty custom collections remain application-defined. - -## Stage 16: Opt-in transient override acquisition - -**Complete.** Opted-in loaders receive ordered, independently copied native -override records with safe flag labels. The root, ckconfig, and ckprompt -workspace suites passed with Go 1.27.0, including scope preflight, comparison -separation, native provenance, and load-error propagation. - -Add `Selection.Overrides []configkit.Override`. Preserve ordered records; nil -means no CLI records. A loader opting in via `scope.Features.Overrides = true` -reads those records during its ordinary load and supplies them to ConfigKit. -Reuse the existing loader signature instead of adding a second loader or trying -to modify an already-loaded result. `FromConfigKit` and `ConfigScope` do not -claim that arbitrary application loaders consume overrides automatically. - -Install repeatable `--set POINTER=JSON` on acquisition commands (`validate`, -`show`, `sources`, `explain`, and `diff`), and `--against-set` on comparisons. -Scope discovery gets no acquisition flags. Parse with a shared ckconfig assignment -helper: split at the first `=`, parse the pointer with native ConfigKit path -syntax, parse one JSON value with `ParseCLIJSON`, and set the safe provenance -label to `--set` or `--against-set`. Syntax/JSON conversion failures are usage -errors. Native restrictions on admissible override paths and combinations remain -load-time ConfigKit errors. Do not prevalidate root/index/schema restrictions, -deduplicate, collapse records, resolve overlaps, or retry a rejected load. - -Only loaders that declared support receive installed override flags for their -scope; reject an unsupported selected mode before acquisition, including mixed -aggregate scope coverage. Supply the same CLI records independently to each -selected ordinary scope that accepts them. Copy CLI-owned record slices and -parsed JSON containers when applied to independently prepared selections; do not -copy arbitrary application runtime objects. For comparison, left and right lists -are independent under OD-9; absence never erases application-owned overrides or -inherits the other side's CLI records. No new clearing flag. - -Document the unsupported `=` in pointer keys and preserve `=` in JSON values. -Verify nested typed values, empty/false/zero/null, duplicate/overlapping records -forwarded in order, safe labels, capability availability, comparison separation, -and propagation of native load errors/provenance. Domain precedence and override -algorithms remain upstream tests. - -## Stage 17: Explanation discovery and metadata - -**Complete.** Explain supports discovery filters and field metadata, with -mode and capability checks before acquisition. `Invocation.Help` renders the -selected command's existing help when no mode is selected, avoiding application -factories. Root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0, -including historical paths, escaped subtrees, and help delivery. - -Extend `config explain` under [OD-4](promptkit-v0.20.0.md#od-4-configuration-path-and-metadata-presentation). -Track supplied `--path` separately from its value; root `--path ''` is an -operation. Bare invocation shows successful command help before input/state -factories or acquisition. Select `--list` or `--path`, with both a usage error. -List-only flags are `--historical`, `--under POINTER`, and -`--explicit=true|false`; reject their use in path mode or without list selection -as an invalid combination rather than silently ignoring them. - -For listing, require declared PathDiscovery and acquired metadata. Enumerate -native HistoricalPaths, use Lookup for current presence and explicitness, and -include historical-only paths only when requested. Obtain History even when -Lookup is absent where detailed explanation requires it. Represent unavailable -current metadata separately from false explicitness. Do not label all -non-explicit values as defaults or enumerate schema fields that never existed. - -Use parsed pointer token boundaries for subtree tests, including root and escaped -keys. A small private pointer-token comparison can consume native paths' String -representations; it must not invent another domain path parser or equate textual -prefixes. Retain native paths and list indexes. Historical-only entries match -neither current explicitness filter. Native path enumeration order is sufficient; -do not add a new ordering guarantee. - -Use a compact discovery report `{scope, paths: [...]}` with per-entry path, -present, and optional metadata containing explicitness when current. Attach a -compact text template; values/history stay out of the list. Extend path-specific -explanation's existing report with native available field metadata, avoiding -repeated evidence. Existing explanation remains usable when PathDiscovery is -absent. Update help, GoDoc, and focused tests for mode/presence/filter behavior, -capabilities, historical-only evidence, and result delivery. - -## Stage 18: Focused effective values and source evidence - -**Complete.** Focused show and source selection use native safe evidence, -including source inventories returned with acquisition failures. Root, -ckconfig, and ckprompt workspace suites passed with Go 1.27.0, including null, -historical-only paths, missing evidence, and delivery failures. - -Add `config show --path POINTER` for one scope with PathShow support. Parse the -pointer before loading, call the acquired native `Explain`, and select its safe -effective snapshot. An absent effective path is operational failure; explicitly -present null succeeds. A historical-only explanation does not supply a current -value. Convert the snapshot YAML through core and submit only the selected value, -without snapshot wrappers or a text template. Whole-document aggregate show -continues Stage 7's map; path plus `--scope all` is a usage error. - -Add `config sources --source-id ID` to existing Sources capability. Filter the -acquired inventory rather than invoking another loader. Retain the ordinary -source report envelope and return its selected single entry; unknown IDs are -operational failures. On acquisition error, report available captured source -inventory, filtered when requested, while preserving the acquisition failure. -If a filter also misses during a failed load, preserve the original cause and -include the selection problem in the explanation rather than replacing the load -error. If evidence is unavailable, say so; do not fabricate an empty inventory. -Source IDs are local to this acquisition. Preserve native locations, version -and destination evidence, and redaction in the existing thin source projection. - -Verify mapping/string/false/zero/null focused display across formats, missing -and historical-only paths, optional capability failure, known/unknown source -selection, available-empty versus unavailable failure evidence, native cause -identity, and presentation failure alongside acquisition failure. Do not read -source files again to recover evidence. - -## Stage 19: Detailed differences and assertion outcomes - -**Complete.** Detailed native difference reports and opt-in assertion status -are implemented. Root, ckconfig, and ckprompt workspace suites passed with Go -1.27.0, including concealed changes, null versus absence, and delivery failures. - -Reuse existing Scope.Compare and native Difference records. Keep concise -additions/changes/deletions as default and add `--details`. The detailed report -is `{scope, differences: [...]}`; entries carry native `path`, `before`, `after`, -and `hidden_changed`. Each snapshot has explicit `present`, `redacted`, and a -safe decoded `value` (null when absent, distinguished by present=false). -Decode only present native snapshots; do not interpret marker-looking strings -as redaction. Use one projection path and ordinary JSON tags, no mirrored -upstream graph or custom omission framework. Empty differences is `[]`, not null. -Both modes have no text template, so automatic output is YAML. - -Add opt-in `--check`. Use native record presence, including concealed changes, -to return a domain outcome with status 3 for differences; equality stays status 0. -Usage and operational errors retain 2 and 1 respectively. Without --check, -successful differences remain success. Render the report before returning the -chosen operation outcome. Preserve a nonzero domain result if presentation also -fails, retaining separate presentation evidence under core outcome rules. - -Verify the same provider calls/loads serve concise and detailed views, native -additions/deletions, null versus absence, hidden changes with equal safe values, -empty results, sequence snapshots remaining atomic, all formats, and assertion -outcomes with writer/render failure. Do not compute equality from displayed YAML, -add a comparison callback, reload data, or implement list matching. - -## Stage 20: Detailed validation and reached-scope aggregation - -**Complete.** Detailed validation filters native findings and reports reached -scopes after acquisition stops, preserving independent diagnostics and causes. -Root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0, including -failure, cancellation, source references, quiet mode, and output failure. - -Complete Stage 7's validation aggregation using Stage 14's evidence. Add -`--details`, repeatable `--severity`, and repeatable `--code` on validation; -filters require detailed mode. Parse severity using native known severities; -codes remain exact native code strings, including future/unmatched strings. -Within one filter match any selected value; across filters match both. Filter -only presentation, never operation outcome. - -Acquire scopes in existing order, stopping at first acquisition failure or -cancellation. Retain completed-scope results and available evidence from the -failing/reached scope. Do not create records claiming unvisited scopes passed. -Submit once after acquisition stops, even if cancellation caused the stop. This -handler must not use an ordinary inspection helper's pre-submission cancellation -guard. Keep native-generated messages in their existing diagnostic lifecycle; -aggregate report timing does not buffer the whole invocation. - -Use one report `{scopes: [...]}` in concise and detailed modes. Each entry names -the scope and its outcome (`valid`, `failed`, or `canceled`); detailed entries -add findings adapted from native records with safe source references, and -distinguish `unavailable`, `empty`, `filtered`, and `present` evidence states. -Use existing thin path/location/source projections, converting native Paths to -operator pointer strings instead of serializing their private storage. Keep -required sources for selected findings, including related locations. Apply the -known-group warning coordination from Stage 14, preserving -unrelated messages and the terminal failure explanation. Concise mode retains -ordinary warnings and a compact text template; detailed mode has the selected -readable text template with scope/outcome followed by findings and locations. -Explicit YAML/JSON renders that same selected report value. - -A failed load establishes no effective configuration. Successfully rendering its -evidence never changes failure to success. Preserve cancellation/load cause and -separate presentation failure. Output errors occur after acquisition has stopped -and cannot undo loads or stop loads already completed. Update the CLI and tests -that formerly stopped on per-scope output failures. - -Verify success, warnings, matched load failure, unavailable/empty evidence, -filters with no matches, source references, known duplicate suppression, -unrelated warnings, aggregate failure/cancellation, one JSON document, quiet -mode, and combined operation/presentation failures. Avoid exact cosmetic -snapshots and upstream validation-rule tests. - -## Stage 21: Simple consumer and core/configuration API exercise - -**Complete.** The simple consumer opts into native overrides and demonstrates -the new inspection and failure workflows. The core consumer's structured report -and template remain exercised. Core example and ckconfig workspace tests passed -with Go 1.27.0. - -Update the maintained [simple ckconfig consumer](../../integrations/ckconfig/examples/simple) -to install an explicitly configured FromConfigKit scope with Overrides enabled, -replacing AppCommand convenience wiring there. Append the selected native CLI -records to its ordinary ConfigKit Options.Overrides during loading, leaving -native conflict handling intact. Declare explicit right-side names for any -selected application selectors. Keep ordinary configuration discovery/default -behavior on omitted sides. Demonstrate metadata -listing, focused values, detailed validation, source filtering, detailed diff, -and assertions through the standard family, not custom duplicate handlers. - -Use the existing before/after fixtures and add `fixtures/invalid.yml` with a -valid schema header plus `greeting: [invalid]`, which cannot decode into the -example string field. Use it for acquired-source and diagnostic delivery, not -to independently test upstream type validation. Extend existing consumer tests -for a representative normal task, a failed-load evidence task, and an -independent comparison/override task. Reuse -lower-layer parsing and rendering coverage; do not duplicate the full mode -matrix here. Show a structured application report and text template in the core -consumer without optional integration imports. Ensure metadata-only operations -do not initialize application runtime state. - -## Stage 22: Composed consumer and application-owned flag reuse - -**Complete.** The composed consumer exercises request preview, namespaces, -reusable flags, independent overrides, and failure evidence with invocation-local -caching. The root, ckconfig, and ckprompt workspace suites passed with Go 1.27.0. - -Update the maintained [composed consumer](../../integrations/ckprompt/examples/composed) -to install `ckprompt.Declarations`, explicit empty native namespace defaults -(enabling root defaults plus opt-in selectors), request preparation, extended -ConfigScope facets, and explicit `against-campaign`/`against-limit` comparison -bindings for their existing applicable scopes. Opt the application scope into -overrides and append its CLI records to ordinary ConfigKit overrides; native -duplicate/overlap errors remain native errors. Reuse the public -CLI flag collections on an application-owned command with its own input type, -showing canonical-only behavior there unless it deliberately installs aliases. -Do not introduce application-internal upstream convenience wrappers. - -Keep the PromptKit configuration scope's Overrides feature false in this -consumer. Released PromptKit Config/ConfigurationSources accept sources but do -not expose a ConfigKit Options.Overrides handoff. OD-11 is explicitly a loader -opt-in; it does not require simulating missing native engine support through -source rewriting. All native inspection/evidence features remain enabled. -Application-owned loaders can declare override support when their own acquisition -boundary actually accepts those records. Aggregate --set preflight must account -for this scope difference rather than dropping an unsupported scope silently. - -Keep successful-load caching application-owned and based on each side's complete -selection, overrides, and supplied domain inputs. A source-selection-only cache -must not incorrectly reuse a result for different overrides or comparison sides. -Use a small invocation-local cache-entry list and `reflect.DeepEqual` on owned -selections and relevant supplied domain fields, retaining those inputs with each -entry. Do not invent a universal hash scheme or cache across invocations. -Retain invocation state lifetime and do not cache failed loads as successes. - -Update request fixtures to use released resource/source contracts and explicit -file-input names. Include short inline input, preview, namespaces, and effective -provider parameters. Keep the native default bundle and existing domain commands -unless the selected target changes their usage; do not freeze catalog counts. -Retain the local fake LLM/probe setup and native finding-versus-operation outcome -semantics. No external credentials or model services in default examples/tests. - -Exercise representative config and prompt workflows, aliases and presence, -builder replacement, rendered preview, failure evidence, independent campaign -selections with overrides, ordinary domain dispatch, and help/version without -loading. Expected native evidence should derive from the selected engine/result; -do not reimplement native resolution tests. - -## Stage 23: Canonical contracts and obsolete infrastructure audit - -**Complete.** Audited the output inventory and public boundaries, removed -unused YAML report tags, aligned current documentation and policy wording, and -tidied integration dependencies. The workspace suites and 20 development example -commands passed with Go 1.27.0; independent integration validation awaits the -released dependencies. - -Review every path in the feature roadmap's -[output inventory](promptkit-v0.20.0.md#output-implementation-inventory). -Remove remaining handler-local format inputs, validators, encoders, legacy -prompt/profile mirrors, inherited comparison helpers, and old document framing. -Do not route raw help, diagnostics, shell protocols, or intentional caller raw -writes through report serialization. Remove direct integration YAML dependencies -only if no legitimate domain/fixture usage remains after `go mod tidy`. - -Complete GoDoc and [CLI reference](../cli.md) updates: universal formats, -representation and text-template behavior, native resources versus prepared -content, flags and scoped aliases, mode/capability availability, metadata and -failure evidence, independent selections/overrides, outcomes, cancellation, and -changed aggregate show/validation delivery. Remove obsolete migration sections -and legacy variants from current guidance as required by the clean-adoption -scope. Historical released notes and tags stay immutable. - -Update the [consumer guide](../consumers/guide.md), current internal inventory, -applicable README/development examples, dependency guidance, and testing policy's -obsolete native-YAML/order requirements. Refer to upstream for domain semantics -rather than copying a parallel specification. Align architecture-policy wording -that describes the former shared comparison selectors with the deliberate new -model; do not add unrelated policy changes or successor ADRs for these -presentation/selector choices. Use maintained examples as complete artifacts. - -Check scope against all roadmap completion criteria and deferred exclusions. -Perform focused documentation/link/fragment, whitespace, notices, and API-boundary -review. No new generic report framework, runtime wrappers, output-contract or -appended-message flags, persistence, live probes, discovery tracing, or secret -bootstrap work enters this sprint. - -## Stage 24: Core release candidate and publication handoff - -**Complete.** Core `v0.4.0` was published from commit -`7416bf6fdc29998e820969ea45e856912afb78cd` after ReleaseKit's candidate checks -and standalone suite passed with Go 1.27.0. Hosted delivery remains separate. -On 2026-11-07 the authoritative `origin` had no ckconfig `v0.4.0` or ckprompt -`v0.3.0` tag; dependent integration releases remain pending. - -Inspect authoritative release state under the [release procedure](../release.md) -before selecting versions. Use the next unused core minor release (expected -v0.4.0 if still unused), a later ckconfig minor release (expected v0.4.0), and -update ckprompt v0.3.0 only if it remains unpublished. If that candidate has been -published, preserve it and select the next unused minor instead. These are -mechanical applications of the existing release policy, not new product decisions. -Record actual versions and source commits here as they become available. - -Prepare the core note, notices, and canonical contracts for the full shared -reporting/input API, with immutable footer links. Explain changed core contracts -concisely; no compatibility adapter or separate migration guide. Use the selected -release toolchain for root standalone tests and the normal candidate preparation. -Commit the reviewed candidate before any publication. - -Core publication is a maintainer handoff requiring separate explicit -authorization. This plan does not authorize push, tags, publication, or hosted -delivery. Without that authorization, finish all available workspace development -and candidate work, report the release dependency pending, and do not claim -final independent integration validation. Do not add polling, CI gates, or an -alternative fake module release to bypass this handoff. After authorized source -publication, proceed to Stage 25. Hosted delivery remains a separate operation. - -## Stage 25: Released core alignment and ckconfig candidate - -**Complete.** Both integration modules select published core `v0.4.0`. -ckconfig `v0.4.0` was published from commit -`bd115c8beef49c8f2566f5b0b2a1dd0e67354378` after its standalone suite and -simple consumer passed against the downloaded core with Go 1.27.0. Hosted -delivery remains separate; ckprompt's independent alignment follows next. - -Pin the actual released core version supplying Stages 1–6 in both integrations. -Download ckconfig dependencies with GOWORK off and collect authentic sums; tidy -that module with the selected toolchain. Defer ckprompt standalone preparation -until Stage 26 supplies its released ckconfig requirement. Keep ConfigKit v1.1.0 -and PromptKit v0.20.0. -Verify core's module graph still has no optional integration dependency. - -Run ckconfig's standalone suite with released core and its maintained simple -consumer. Prepare and commit the ckconfig minor note, attribution, dependency -metadata, and applicable guidance. The note covers shared reporting, new CLI -modes/override opt-in, independent selections, and assertions directly, with the -module-specific immutable footer. Do not edit older released notes. - -Publication of this candidate is the second separately authorized maintainer -handoff. Until it occurs, ckprompt workspace results remain useful but do not -prove its independent dependency graph. Preserve that distinction in status. -After authorized ckconfig source publication, continue with its real released -version; hosted delivery remains separately tracked under the release procedure. - -## Stage 26: Final ckprompt alignment and end-to-end verification - -**Complete.** ckprompt v0.3.0 selects published core v0.4.0 and ckconfig -v0.4.0, ConfigKit v1.1.0, and PromptKit v0.20.0. All three standalone suites -and all three workspace suites passed with Go 1.27.0. Offline tidy left all -module files unchanged. Fifteen documented standalone consumer invocations and -16 additional workflows passed; the two invalid-fixture invocations returned -their expected failures, as did native type rejection for zero/list overrides. -Comparison assertions returned status 3, null overrides retained native evidence, -and preview and smoke commands used the local fake client. ckprompt publication -and hosted delivery remain separate operations. - -The tested fixtures are identified by Git blob IDs: - -| Consumer | Fixture | Blob | -| --- | --- | --- | -| simple | `before.yml` | `8192e75eb483dc5e206956632ecc36a641ead935` | -| simple | `after.yml` | `a5fc1041a8756cfa8487b8abf9ed2e551bdba0d9` | -| simple | `invalid.yml` | `455a1af8e1dd11cb728fce4334fb10d1b1d4ce2b` | -| composed | `before.yml` | `9fc0c68178fea64b5ab5a46e547e25f82baf8c17` | -| composed | `after.yml` | `e1c77fd6004b3114728c245648e01998e6a45858` | -| composed | `topic.txt` | `4c1c8cf49d7b36c033b144ff0ec064f832f11283` | -| composed | `notes.txt` | `4a5e2c8ddb220ae2bbc50868baab9cbbaa0a6263` | - -Pin released core and ckconfig versions providing the new APIs in ckprompt. -Download and tidy with GOWORK off; retain real sums. Update the unpublished -ckprompt candidate note (or fresh minor selected in Stage 24) with the final -capabilities and pinned dependencies, correct product/version title, and -module-specific immutable licensing footer. Record final module identities here. -No code may depend on the temporary workspace to hide old requirements. - -With Go 1.27.0 selected, run the independent suites from the repository root: - -```sh -GOWORK=off GOTOOLCHAIN=local go test ./... -(cd integrations/ckconfig && GOWORK=off GOTOOLCHAIN=local go test ./...) -(cd integrations/ckprompt && GOWORK=off GOTOOLCHAIN=local go test ./...) -``` - -Then validate the aligned workspace: - -```sh -GOTOOLCHAIN=local go test ./... -GOTOOLCHAIN=local go test ./integrations/ckconfig/... -GOTOOLCHAIN=local go test ./integrations/ckprompt/... -``` - -Confirm tidy produces no remaining module changes after preparation. Format -changed Go files and check public facade/backend import direction, documentation -links/fragments, attribution pins, intended files, and staged/unstaged whitespace. -Use graph tools first for code discovery and ordinary searches for literals, -configuration, and docs. Reuse successful checks for unchanged content; root -`./...` alone is not integration coverage. - -Run maintained consumers outside the workspace for these representative tasks, -using their final installed features and fixtures: - -- Automatic and explicit text/YAML/JSON application/version reports. -- Whole/aggregate/focused config display; metadata listing and root explanation. -- Independent campaign/config comparisons, --details, --check, and both override - sides, including zero/null/list values through standard syntax. -- Invalid-load sources and detailed validation retaining a nonzero operation - outcome, and all-scope validation producing one reached-scope report. -- Native prompt/profile/backend inspection; prepared preview with inline and file - inputs, aliases, namespaces, and provider parameters; requirements validation. -- A deterministic single smoke and `test all` with the configured local client, - retaining native findings and separate operation/presentation semantics. - -From `integrations/ckconfig/examples/simple`, representative final invocations -are: - -```sh -GOWORK=off GOTOOLCHAIN=local go run . config explain --list -GOWORK=off GOTOOLCHAIN=local go run . config show --path /greeting --format json -GOWORK=off GOTOOLCHAIN=local go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml --details -GOWORK=off GOTOOLCHAIN=local go run . config validate --config fixtures/invalid.yml --details --format json -GOWORK=off GOTOOLCHAIN=local go run . config sources --config fixtures/invalid.yml -``` - -The invalid-load invocations intentionally fail while reporting available -evidence. From `integrations/ckprompt/examples/composed`, run: - -```sh -GOWORK=off GOTOOLCHAIN=local go run . config show --scope all --format json -GOWORK=off GOTOOLCHAIN=local go run . config validate --scope all --campaign spring --limit=0 --details -GOWORK=off GOTOOLCHAIN=local go run . config diff --scope app --campaign spring --limit=0 --against-campaign autumn --against-limit=0 --details -GOWORK=off GOTOOLCHAIN=local go run . config diff --scope app --set '/campaigns/spring/model="left"' --against-set '/campaigns/spring/model="right"' --details -GOWORK=off GOTOOLCHAIN=local go run . promptkit show prompt briefing --campaign spring --prompt-namespace field-notes -GOWORK=off GOTOOLCHAIN=local go run . promptkit show profile spring --campaign spring -GOWORK=off GOTOOLCHAIN=local go run . promptkit show backend local --campaign spring -GOWORK=off GOTOOLCHAIN=local go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}' -GOWORK=off GOTOOLCHAIN=local go run . promptkit requirements validate briefing --campaign spring --input-file topic=fixtures/topic.txt -GOWORK=off GOTOOLCHAIN=local go run . promptkit test all --campaign spring --prompt briefing --profile spring -``` - -Record actual outcomes and final fixture identities. Use existing consumer tests -to assert native application statuses (including --check status 3); the `go run` -wrapper itself does not preserve a child program's nonzero status code. Existing -focused unit/integration tests own injected cancellation and writer failures; -do not build another exhaustive consumer harness. Default verification stays offline -after dependencies are prepared. - -Audit each completed stage against its behavior and the feature roadmap, remove -leftover migration scaffolding, review the complete diff, and commit the final -candidate. Keep feature/implementation status accurate and preserve deferred -items in future.md when retiring completed records under repository policy. -ckprompt publication and hosted delivery remain separate authorized operations; -preparing this candidate does not perform them. Do not mark the full dependency -alignment complete until both preceding release handoffs and independent suites -have actually succeeded. - -## Open Questions - -None requiring a product or scope decision. API and transition choices are -selected above. Core and ckconfig publication authorization is an explicit -external dependency in Stages 24–25, already required by OD-7 and release policy; -it is not implicit authority granted by an implementation prompt. Exact unused -versions and release commits are established from authoritative state at those -handoffs, without weakening independent-module completion criteria. diff --git a/docs/roadmap/promptkit-v0.20.0.md b/docs/roadmap/promptkit-v0.20.0.md deleted file mode 100644 index f5d1ae0..0000000 --- a/docs/roadmap/promptkit-v0.20.0.md +++ /dev/null @@ -1,1416 +0,0 @@ -# Shared report output, PromptKit v0.20.0 adoption, and ConfigKit operator CLI - -Status: implementation complete. Core v0.4.0 and ckconfig v0.4.0 are published; -the ckprompt v0.3.0 candidate is prepared for separate publication. The -[implementation plan](implementation.md) records stage completion and validation; -native resource report fields follow upstream. Practical beta feedback will guide -presentation refinements. - -Reading guide: the core prerequisite sections own shared mechanics; resource -inspection and OD-1 through OD-11 own integration behavior. The overview links -to those decisions, and the completion checklist identifies verification -boundaries without redefining policy. - -## Ownership principles - -The [architecture ownership table](../policy/architecture.md#ownership-boundaries) -and [Go types and facilities policy](../policy/architecture.md#go-types-and-facilities) -now own the agreed principles. Core supplies CLI mechanics and output formatting; -applications and integrations choose report content, and upstream libraries own -domain semantics. This roadmap owns the desired target and its specific input, -serialization, and presentation contracts. The -[implementation plan](implementation.md) owns the steps from the current -baseline to that target. - -## Purpose and ownership - -Adopt released PromptKit v0.20.0 and expose useful operator tasks through -standard CommandKit commands, flags, and reports. This roadmap covers CLI -exposure, including ConfigKit v1.1.0 operator features in `ckconfig`, with shared -core reporting and CLI input capabilities as prerequisites to the downstream work. -Core standardizes report format selection, representation, rendering, and -delivery for core commands, integrations, and application-owned commands. -Applications and integrations continue to choose report content. This does not -turn `ckprompt` into a convenience library for application-internal PromptKit -operations. Applications continue to own engine construction, domain inputs, -credentials, execution, and their executable lifecycle. - -`ckprompt` neutrally exposes the released upstream capabilities and their returned -evidence. CommandKit is in alpha with no consumers: implement a clean adoption -of v0.20.0, with no backward-compatibility adapters, legacy report shapes, or -consumer migration guidance. Update the final API, CLI documentation, examples, -and candidate notes to describe the selected behavior directly. - -The [architecture policy](../policy/architecture.md), -[optional-module decision](../adr/0004-optional-integration-modules.md), and -[reporting decision](../adr/0006-invocation-reporting.md) govern implementation. -The [CLI reference](../cli.md) and public GoDoc remain the owners of implemented -contracts. This roadmap records planned work, not new guarantees about upstream -behavior or permanent limits on future features. - -## Baseline and released evidence - -Planning baseline: `e90821331874c926eb5f95216dc2bb4bcbf4a115`. The table -below distinguishes the implemented dependencies from the selected target. - -| Component | Current baseline | Target | -| --- | --- | --- | -| Core | `go.maximumdirect.net/commandkit`; Go 1.26.0 minimum | Shared report output, public CLI JSON parsing, and ordered typed input composition. Text/YAML/JSON land together. Collections and aliases retain existing declaration APIs. | -| `ckconfig` | ConfigKit v1.1.0; Go 1.27.0; core v0.3.0 | Adopt the new core reporting API, shared CLI inspection extensions, and an appropriate module release. | -| `ckprompt` | PromptKit v0.18.0; ConfigKit v1.1.0; ckconfig/core v0.3.0; Go 1.27.0 | Adopt the new core reporting API, PromptKit v0.20.0, and the ckconfig version delivering the shared work. | -| Candidate | [ckprompt v0.3.0](../../integrations/ckprompt/docs/releases/v0.3.0.md), recorded as unpublished | Update the unpublished candidate after checking its status during implementation. | -| Local workspace | Core and both integrations, Go 1.27.0 | Validate local composition and independent modules separately. | - -Use PromptKit tag `v0.20.0`, commit -`8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf`. Its Go minimum remains -1.27.0 and its ConfigKit dependency remains v1.1.0. Reviewed sources are the -[release notes](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/releases/v0.20.0.md), -[request and report types](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/types.go), -[resource inspection reports](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/resource_inspection.go), -[configuration and execution semantics](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/formats.md), -[engine API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/engine.go), -[namespace API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/namespaces.go), -[configuration inspection API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/configuration_inspection.go), -and [smoke API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/smoke_diagnostics.go). -Work against released versions only; do not inspect or monitor unreleased -upstream work in anticipation of another adoption. - -ConfigKit v1.1.0 is already adopted at released commit -`191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9`. Its -[inspection API](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/inspection.go), -[metadata API](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/metadata.go), -and [configuration reference](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/config.md) -support the additional CLI work below without an upstream dependency upgrade. -Its matched history for registered records moving within lists flows through -native inspection; it does not introduce identity-based CLI paths or -element-level effective diffs. - -Current `ckprompt` supplies prompt/profile inspection, requirements discovery, -concrete request validation, prompt/profile/backend/namespace/collection -catalogs, and four smoke operations plus `test all`. Smoke commands already -expose most execution overrides and detailed native evidence. Validation has -profile, session, variable, and file-input flags but lacks that override surface. -There is no concrete request preview or dedicated backend detail command. - -Current `ckconfig` supplies validation, native effective YAML, source inventory, -path explanation with history, and reduced semantic comparison. Its `View` -contains effective, sources, and explanation facets. Native metadata is not -exposed as a capability. `config sources` returns on acquisition failure before -rendering evidence; loaders convert native diagnostics into presentation -messages but do not expose a structured diagnostics report. Relevant boundaries -are [ckconfig contracts](../../integrations/ckconfig/contracts.go), -[ConfigKit adapters](../../integrations/ckconfig/configkit_adapter.go), and -[PromptKit adapters](../../integrations/ckprompt/adapters.go). - -Effective display currently writes the whole configuration. Sources are reported -as a complete inventory. Comparison accepts independent config/overlay choices, -but applies the same application selectors to both typed inputs and succeeds -when a comparison reports differences. The new tasks extend those boundaries; -they do not replace already-delivered explanation or smoke functionality. - -## Targeted end state - -First establish the [shared core report output capability](#shared-core-report-output-prerequisite). -The integration work below uses that public API instead of adding independent -format-selection and encoding machinery in each module. The -[core input prerequisites](#shared-core-cli-input-prerequisites) provide shared -CLI JSON parsing and the required cross-flag input ordering. - -The adoption includes: - -1. Update the dependency, checksums, attribution, and unpublished candidate note - to the released v0.20.0 target. -2. Use the released resource inspection types and document the operator-facing - distinctions among resources, configuration evidence, and prepared requests. -3. Cover native resource reports/errors, authentication response-limit evidence, - and smoke preparation-error propagation at CommandKit's boundary. -4. Validate the final independent modules and aligned workspace. - -Deliver the following operator capabilities. The resource inspection section -and numbered decisions own syntax and behavior; these examples summarize tasks. - -| Operator task | CLI examples | Owning module and report | -| --- | --- | --- | -| Inspect a captured prompt definition | `promptkit show prompt PROMPT_ID` | `ckprompt`: native `PromptInspection`, including unrendered messages and presence-aware metadata. | -| Inspect a resolved profile resource | `promptkit show profile PROFILE_ID` | `ckprompt`: native `ProfileInspection`, before backend completion and request overrides. | -| Inspect backend settings without running a probe | `promptkit show backend BACKEND_ID` | `ckprompt`: native `BackendInspection`, including configured smoke diagnostics. | -| Inspect what a concrete prompt request prepares | `promptkit show prepared PROMPT_ID --profile … --input-file … --var …` | `ckprompt`: YAML report of selected IDs, effective settings, rendered/appended messages, output contract and schema, session, hashes, and timing from `PreparedRun`. | -| Supply a short sample to one prompt without creating a file | `promptkit show prepared PROMPT_ID --input NAME=TEXT`; also request validation | `ckprompt`: native inline input for single-prompt preparation; file input remains available through `--input-file NAME=PATH`. | -| Reproduce target/provider settings without editing configuration | Applicable existing smoke override flags on validation and preview; `--llm-extra-params JSON` on these and smoke operations | `ckprompt`: native request forwarding; preview and smoke reports show returned effective settings. | -| Resolve unqualified resource selections in chosen namespaces | Independent prompt/profile/backend namespace flags | `ckprompt`: delegate to native namespace views, retaining the distinction from catalog filters. | -| Find configuration paths and inspect their explicitness | `config explain --list --scope promptkit`, with historical selection; metadata alongside path explanation | `ckconfig`, wired through `ckprompt.ConfigScope`: observed paths, effective presence, explicitness/null/origin evidence, and available history. | -| Understand both sides of configuration changes | `config diff --scope promptkit --details` | `ckconfig`: native paths, left/right snapshots, presence/redaction, and hidden-change evidence. | -| Investigate a failed configuration load | `config sources --scope promptkit` on failure; `config validate --details --scope promptkit` | `ckconfig`, with both native adapters: acquired source inventory and native codes, severities, paths, and locations while retaining the load failure. | -| Inspect one effective value or subtree | `config show --scope app --path /server` | `ckconfig`: the selected native effective snapshot, retaining redaction and absence/null distinctions. | -| Follow a source reference | `config sources --source-id ID` | `ckconfig`: the matching acquired source record, including evidence available after failure. | -| Compare different application selections | For example, `config diff --campaign spring --against-campaign autumn` | `ckconfig`: independently prepared typed inputs passed to the existing native comparison provider. | -| Detect configuration differences in scripts | `config diff --check` | `ckconfig`: a deliberate difference outcome based on native records, alongside the selected comparison report. | -| Narrow an inspection to relevant evidence | Subtree/explicitness filters on explanation discovery; severity/code filters on validation diagnostics | `ckconfig`: filtered native evidence with source references retained. | - -The configuration suite retains six subcommands: `scopes`, `validate`, `show`, -`sources`, `explain`, and `diff`. Path discovery belongs within `config explain`; -structured diagnostics belong within `config validate`. This command placement -is agreed. OD-4 selects `--list` and `--path` as the explanation modes, with -help on a bare invocation. OD-6 selects `config validate --details` for detailed -diagnostics while retaining concise validation by default. Initial report -presentation and filter spellings are selected under OD-4, OD-6, and OD-8; exact -Go projections can be refined during implementation. No separate path inventory -or diagnostics subcommand is planned. - -Transient configuration overrides are included under OD-11 as an opt-in loader -capability. `config validate --set /workers=0` and -`config show --set /server/port=8080` apply temporary overrides during acquisition -without editing source files. OD-11 selects simple assignment syntax and normal -load-time forwarding; paths containing `=` are unsupported by these flags. Comparison -overrides follow OD-9's independent-side model: `--set` affects only the left -side and `--against-set` only the right. - -### Resource inspection - -Expose `promptkit show prompt PROMPT_ID`, `promptkit show profile PROFILE_ID`, -and `promptkit show backend BACKEND_ID` as peer resource commands. Each selects -one resource through its corresponding released `Engine.Inspect*` API and hands -the returned `PromptInspection`, `ProfileInspection`, or `BackendInspection` -directly to core. Use the full native report, without a separate summary/details -mode or a dedicated text template. The structured mapping automatically selects -YAML; explicit JSON or text uses the same core rendering rules and content. -Remove the duplicated prompt/profile report structs and per-field formatters. - -The upstream report types own the fields and their meanings: - -- Prompt inspection includes captured, unrendered inline or imported messages, - cache metadata, declared inputs, description/session/default-profile metadata, - output settings, and the opaque prompt hash. Referenced profiles and schemas - are not resolved by this inspection. -- Profile inspection exposes the resolved profile after composition and sibling - inheritance, before backend completion, execution defaults, or request - overrides. An omitted endpoint is not evidence that the completed request - lacks one. Use `show prepared` to see completed request settings; do not - reconstruct an effective target inside the profile command. -- Backend inspection includes its endpoint, credential environment reference, - concurrency/queue configuration, provider parameters, and configured smoke - diagnostics. These are configured settings, not live capacity occupancy, - derived probe destinations, or probe results. Actual smoke operations remain - under `promptkit test`. - -Preserve native omission and presence, including explicit empty strings, zero, -false, and empty collections. Do not fill absent resource fields with execution -defaults or infer provenance from nil pointers. Configuration inspection through -`config show` and `config explain` remains the source of effective configuration, -explicit null, and provenance evidence; resource reports do not replace it. - -Add an independently optional backend-inspection callback to `Suite`, following -the prompt/profile acquisition pattern, and wire it through `FromEngine`. A nil -callback omits only that command. Use the standard configuration/application -selectors and input/state/diagnostic lifecycle. Backend selection is a positional -ID; install only its applicable namespace control under OD-3, without request -execution overrides, profile selection, or a redundant backend flag. Help and -completion reflect capability availability without acquiring an engine. - -Preserve acquisition failures, cancellation, and supported native error identity, -including `ErrBackendNotFound`; do not relabel an absent backend as -`ErrInvalidRequest` or fabricate an empty successful report. Use the existing -operational-outcome and presentation-failure paths. - -Help distinguishes captured resource content from rendered request content. -Application acquisition can load sources and capture message files; the resource -inspection call itself does not prepare requests, read schemas or request inputs, -resolve credentials, or contact providers. Inspection success is not a readiness -check. Credential environment references are names, not resolved secrets, but -arbitrary prompt and provider content is not guaranteed safe for public disclosure. - -### Released upstream semantics - -Adopt PromptKit v0.20.0 semantics directly. Keep operator help focused on the -selected operation and link to upstream contracts for domain rules: - -- After configuration composition and inheritance, profile null endpoint, - credential source, and whole provider map permit backend defaults. Empty - strings explicitly clear the endpoint or credential source; an empty provider - map does not suppress backend entries. Profile-level whole-map suppression - is not an upstream operation. Nested provider nulls remain literal data. - ConfigKit's inspection still records explicit nulls and their provenance. -- `api_key_required`, when present and true, requires a usable direct or - environment credential and can coexist with an explicit profile `api_key_env`. - A required key with an absent/null profile source suppresses the backend - credential source. Inspection does not establish credential availability. -- Request provider overrides retain their native whole-map replacement behavior, - separate from configuration composition. Do not impose source-construction - restrictions on runtime request flags or reimplement upstream merging rules. -- Preparation uses self-contained schemas. Preserve native preparation failures - and their causes; resource inspection reports a schema reference without - loading or validating it. Upstream owns schema acceptance and resolution. - -The authentication response-limit reason is evidence of unknown credential -acceptance. Forward native findings without converting false, unknown, -unsupported, or incomplete observations into command failures. Actual -preparation/operation errors retain the operational outcome and supported cause -identity. Native errors and their categories remain upstream-owned. - -Programmatic `PromptSource`, profile/backend source construction, custom artifact -readers, and backend sibling-inheritance helpers remain application-owned upstream -APIs. Maintained examples must use the released contracts, but this adoption adds -no CommandKit wrappers or CLI commands for those construction conveniences. - -### Preview and request flags - -[OD-1](#od-1-preview-command-and-report-presentation) owns prepared preview; -[OD-2](#od-2-request-controls-and-provider-parameter-grammar) owns reusable flag -collections, aliases, input forms, and precedence. Expose preview as an independent -capability alongside existing suite callbacks. Call `Engine.Prepare` once and -hand its native snapshot to core under OD-1; a preliminary `ValidateRequest` -call is unnecessary. -Upstream excludes resolved credentials from prepared settings, but rendered -application content is not a redacted configuration report. - -Build collections using `CommandSpec[I].Flags`, typed constructors, and -`Supplied[T]`. Existing [CaptureFlags and FlagValues.ApplyTo](../../flag_values.go) -serve ordinary deferred application. Collections and alias generation need no -new abstraction; cross-flag input ordering and shared JSON parsing use the -[additional core input prerequisites](#shared-core-cli-input-prerequisites). -Applications retain their input types, request construction, acquisition, and -execution. Keep execution-target overrides distinct from transient retries: -ordinary requests and smoke diagnostics have different upstream retry defaults. - -### Namespace selection - -[OD-3](#od-3-namespace-flags-and-loader-defaults) owns the opt-in namespace -composition, applicability table, and profile-identity clarification. Implement -one native view update using declared defaults and supplied fields. Verify the -selected flags against actual upstream operations; captured references and -catalog filters retain their upstream meanings. - -### Shared configuration capabilities - -Extend `ckconfig` through optional capabilities, exposed by `FromConfigKit` and -`ckprompt.ConfigScope`. Providers need not implement every inspection mode; -help and availability must reflect their supplied capabilities. - -- Metadata discovery uses `Metadata.HistoricalPaths`, `Lookup`, `IsExplicit`, - and `History`. It covers observed paths, not every possible schema field. - Preserve history after absent lookup and native list-index paths. OD-4 owns - the operator presentation and filters. -- Detailed diff reuses `Scope.Compare` and native `Difference` records under - OD-5. Native sequence changes remain atomic; no element-matching algorithm or - reloadable patch format is added. -- Failed-load evidence uses `LoadError.Sources()` and `Diagnostics()` alongside - the original error. Acquisition must distinguish unavailable evidence from an - available empty inventory. A failed load establishes no effective configuration - or metadata capability. OD-6 owns diagnostic presentation, aggregation, and - failure delivery; this work requires adapter changes, not only a renderer. - -### Additional ConfigKit operator workflows - -[OD-8](#od-8-focused-configuration-reports-and-filtering) owns focused values and -source selection. Obtain path values from native `Explain(path)` and whole -configuration values from safe `WriteEffective` output, converting both through -core. Never reconstruct inspection from mutable `Result.Config` or source files. -Select source IDs from acquired inventory; native `Source(id)` is a convenience, -not another provider requirement. Source IDs are local to one load. - -[OD-9](#od-9-independent-comparison-selector-bindings) replaces the -[current comparison inheritance](../cli.md#compare-configuration-selections) -while retaining the two-input/provider lifecycle. Domain defaults and caching -remain application-owned. -[OD-10](#od-10-comparison-assertion-outcomes) uses native differences for assertions; -source/history differences alone and changed credential bytes behind unchanged -references are not necessarily effective-value differences. - -[OD-11](#od-11-transient-configuration-overrides) owns temporary override syntax -and forwarding. ConfigKit recursively overlays mapping overrides and replaces -sequences, unlike PromptKit's complete provider-map replacement. Shared numeric -parsing must not erase that distinction. Source-load errors remain errors even -if a supplied override would replace the affected value. - -## Shared core report output prerequisite - -**Agreed scope:** add a first-class public reporting capability to CommandKit -core before implementing the downstream integration additions. An application -or integration gathers report data and hands it to core; core selects the -default or operator-requested format, renders the report, and delivers it. -Centralize formatting and translation machinery to the greatest practical -extent so commands share output conventions and avoid repeated infrastructure. -Core remains independent of ConfigKit and PromptKit types and domain semantics. - -Deliver plain text, YAML, and JSON together in the same core feature release, -implemented in separate reviewable units as useful. Exercise all three before -downstream integration additions depend on the API, so representation decisions -are validated across formats. XML is removed from current consideration. -Markdown is not selected for this adoption. New core formats must work with -existing commands without handler refactoring or -per-command encoder registration. This supersedes both the optional YAML-helper -proposal and earlier YAML-only report restrictions. Keep implementation -proportionate; the [implementation plan](implementation.md) selects public -handoffs and the representation approach. - -### Agreed universal and automatic format selection - -Core owns the universal `--format` flag, its available options, help, input -validation, and renderer selection. Commands do not maintain format allowlists; -adding a renderer and format option in core makes it available to existing -commands automatically. An unknown format is a usage error before acquisition -or other command work. Use one format flag rather than separate format flags. - -The initial public API does not offer command-specific format defaults. Resolve -the effective format in this order: - -1. The operator's explicit `--format` choice. -2. Text when the report handoff includes a text template. -3. Core's automatic selection from the shared report representation below. - -| Report content, without a text template | Automatic format | -| --- | --- | -| String | Text | -| Nonempty sequence containing only strings | Text, one item per line | -| Number or boolean | Text | -| Mapping, including an empty mapping | YAML | -| Sequence of mappings, nested sequences, or mixed values | YAML | -| Empty sequence or null | YAML, keeping the empty result visible | - -Inspect the logical report representation after the selected serialization and -adaptation rules, not just the original Go type. A struct normally represents a -mapping, while a custom serializer may represent that value as a string. Use the -outer shape; do not search inside mappings for a presumed primary field. Select -once for the complete logical report, not independently for each item in a -result collection. - -Omitting `--format` means "CommandKit chooses," not a fixed text default. The -choice can vary with the result: a populated string list yields text, while an -empty list yields YAML `[]`. Explicit selection provides a predictable format -when needed, including `config show --format yaml` for a configuration document -even when the selected value is a string. Core can deliberately evolve its -automatic policy in a future release. - -This supersedes optional command defaults and the proposed per-command default -inventory, including explicit YAML defaults for `config show`, `config diff`, -and prepared-request preview. Applications choose report content and optional -text templates; core selects the format. Reconsider command overrides only for -a concrete demonstrated requirement. - -For `config show`, hand off the selected logical configuration value, not a -string containing serialized YAML or a snapshot metadata wrapper. With no text -template, a configuration mapping naturally selects YAML and a selected string -value selects text. Native snapshot adaptation must preserve that distinction. - -### Agreed format-independent reporting operation - -The application or integration decides what content to report, including which -information appears normally and what is added by `--details`. Core does not -select domain facts, add detail when a format changes, or infer a summary. -Retain the agreed `--details` spelling for the standard commands. - -Provide one public operation through the invocation Reporter that accepts the -selected report data and an optional plain-text template, without requiring a -handler to switch on the selected format or configure an encoder. Core renders -both concise and detailed report values. `invocation.Reporter().Report(report)` -illustrates the intended operation only; it is not a selected signature or an -existing API. - -Provide a corresponding writer-based API for rendering outside an invocation. -Both entry points share the rendering implementation. Invocation reporting uses -the existing Reporter lifecycle for visibility, destinations, delivery, and -presentation failures, preserving domain outcomes and causes. This extends the -existing reporting facility rather than creating a second delivery lifecycle. - -Integration handlers decide whether cancellation stops report submission or -whether already-acquired evidence should still be reported. Core renders the -submitted content through its ordinary visibility and presentation-failure -lifecycle; do not introduce a blanket invocation-cancellation check that discards -such evidence. Ordinary inspection can stop before submission, while smoke -reports and OD-6 aggregate validation preserve available evidence after -cancellation. This does not resume canceled acquisition or execution work. - -### Agreed shared representation rules - -**Agreed:** use Go's standard `encoding/json` serialization conventions to -interpret ordinary Go report values for core serialization. Prepare one logical -representation for YAML/JSON output and for automatic selection and text -rendering when no text template is used. Application-supplied text templates instead -receive the original Go value, as specified below. JSON conventions do not -select JSON as the default output format or expose core's intermediate data -representation as a public template contract. - -Reuse the standard library's field selection, JSON tags, omission rules, nested -value handling, and supported custom JSON serialization. Avoid a new CommandKit -tag convention or reflection-based serialization engine. Suitable upstream -values can reuse their existing JSON contract; thin projections remain useful -when the desired operator content differs from that representation. - -- **One serialized field interpretation.** JSON field tags and custom - serialization govern ordinary values in core-serialized outputs. Conflicting - YAML tags or YAML-specific serialization do not change that interpretation. - For example, a field tagged - `json:"retry_count" yaml:"retries"` appears as `retry_count` in both JSON and - YAML. Do not independently serialize the original Go value with each encoder. -- **Explicit omission.** Honor omissions selected by the JSON contract. Core - does not additionally hide zero, false, empty, or null values for brevity. - Preserve the remaining distinctions among absent, null, false, zero, and empty - values through conversion and rendering. -- **Preserved numeric values.** Avoid precision loss in intermediate conversion, - including accidental rounding of large integers through floating point. This - preserves the serialized value rather than promising precision beyond the - supplied value and its serialization contract. -- **Observable failures.** When serialization is used, values rejected by its - contract produce presentation errors through the existing reporting lifecycle. - Do not silently drop unsupported data or substitute arbitrary string - representations. Templated text executes against the original value without - requiring a JSON round trip. - -**Agreed configuration input conversion:** decode upstream safe inspection YAML -into ordinary Go report values, then use the same shared representation and -renderers as other reports. Core owns the explicit YAML-input conversion helper; -ordinary report strings are never heuristically parsed as YAML. This supersedes -the proposed separate native-YAML preservation path. - -Preserve meaningful data: strings versus numbers and booleans, null versus empty -collections, absent versus present false/zero/null, numeric precision, sequence -order, and upstream redaction. Retain presence and other inspection metadata -where the selected report calls for it. Mapping order, comments, whitespace, -quoting, block/flow style, and exact numeric spelling are not preservation -requirements. Unsupported conversion must remain observable rather than silently -changing meaning. ConfigKit v1.1.0's safe inspection YAML already represents a -restricted, JSON-like value model, making this conversion proportionate. - -Obtain those values from upstream safe inspection output, not application runtime -configuration structs: the latter may lose the captured snapshot, field inclusion, -disclosure rules, or inspection evidence. This is an output conversion, not a -replacement for upstream configuration loading or validation. No lossless YAML -document model or second rendering pipeline is needed. - -When implementation lands, update the -[current display contract](../cli.md#show-effective-configuration) to replace -native-writer and mapping-order requirements. The aggregate presentation decision -below also replaces separate-document framing. These presentation changes follow -the ownership boundary in [ADR 0006](../adr/0006-invocation-reporting.md); they do -not require a separate successor ADR. Current display behavior remains in force -until the implementation and its canonical contracts change. - -This approach reduces new machinery by reusing standard serialization and -centralizing the remaining conversion and rendering work. Exact internal -representation and adapter APIs remain implementation design tasks; a large -public document model is not selected. Validate representative reports before -assuming that an upstream type can be handed off without adaptation. - -### Agreed plain-text rendering - -**Agreed template boundary:** applications and integrations own the report value -and optional text template. Core prepares and executes templates using Go's -built-in `text/template`, passing the original Go value supplied in the report -handoff. Templates use Go field names, types, and standard template behavior, -not JSON field names or CommandKit's intermediate representation. For example, -a Go field `PromptID` tagged `json:"prompt_id"` is accessed as `.PromptID`. - -JSON tags and custom JSON serialization govern structured rendering, not the -template's field access. An exported field tagged `json:"-"` remains accessible -to the application's template, and custom JSON serialization does not replace -the template input. The application owns that text content choice. Core retains -ownership of execution, shared helpers, delivery, and presentation failures. -Prefer reusable templates prepared during setup. Exact preparation and handoff -signatures remain implementation choices; begin with standard template functions -and add shared helpers only for concrete report needs. - -When text is selected and a template is supplied, execute it as supplied and -deliver its output without applying a second formatting pass. Template syntax -or execution errors are errors, not a reason to fall back to another renderer. -Use standard `text/template` semantics rather than introducing a new template -language. A template selects text automatically only when the operator omits -`--format`; explicit YAML or JSON takes precedence and does not execute it. - -**Agreed text behavior without a template:** use core's logical report -representation to select the following rendering behavior: - -- Print strings directly, nonempty sequences containing only strings one item per line, - and numbers or booleans as their values. -- For mappings, nested or mixed collections, empty collections, and null, reuse - the shared YAML renderer. Empty sequences use this rule even when their Go - element type is string, retaining the visible `[]` result. - -Automatic selection already chooses YAML for the second group. The additional -case is explicit `--format text` with structured data and no template, such as -`config show --format text`. Text and YAML intentionally coincide in that case. -This retains universal format support without a separate hierarchical text -renderer or pretty-printer. It supersedes the proposed generic text outline. -Applications do not supply separate YAML/JSON writers, and a failing template -never enters this no-template path. - -### Agreed aggregate configuration presentation - -**Agreed:** `config show --scope all` produces one mapping keyed by the unique -scope identifiers. Each value is that scope's safe effective configuration: - -```yaml -app: - server: - port: 8080 -promptkit: - backends: - - id: local - endpoint: https://example.test/v1 -``` - -The example illustrates the report shape. Scope names sit outside each -configuration's namespace; no `scope` or `config` metadata field is inserted -into the configuration. Keep the scope-keyed mapping even when only one scope -is registered. Single-scope display continues to return the configuration value -directly, without a scope wrapper. - -`ckconfig` collects the safe values and hands the complete ordinary Go mapping -to core once. Core renders it using the shared machinery: automatic selection -chooses YAML, explicit JSON renders the same mapping, and explicit text without -a template uses the YAML fallback. No separate-document output or special core -multi-result rendering API is needed. Applications and integrations choose how -to group other reports using ordinary report values. - -Scope order has no semantic significance or output-order guarantee in this -aggregate mapping. Retain the existing availability checks and acquisition -behavior: acquire all selected views and complete provider-required validation -before report output begins; a failure prevents the combined display. The new -shape does not introduce partial-success output. - -When implementation lands, update the CLI display contract and affected tests -for this aggregate shape. Scope discovery and acquisition ordering are unchanged. -The capability model in [ADR 0003](../adr/0003-configuration-scopes.md) does not -prescribe report framing or mapping order. - -### Remaining core reporting implementation details - -The [implementation plan](implementation.md) selects public signatures, reusable -template preparation, flag integration/collision handling, and replacement of -existing format plumbing. The decisions above do not reopen content -selection, JSON conventions for core serialization, original Go values for text -templates, no-template text rendering, universal formats, automatic selection, -safe YAML input conversion, aggregate configuration presentation, or joint -format delivery. -Report serialization is separate from the agreed CLI JSON number policy in OD-2, -also adopted for configuration overrides in OD-11. - -## Shared core CLI input prerequisites - -These two narrow capabilities land with the core reporting prerequisite. They -support the selected integration behavior without adding a collection framework. - -### Public CLI JSON parsing boundary - -Add a small public CLI JSON parsing entry point to core. It parses one JSON value -using the [OD-2 numeric policy](#od-2-request-controls-and-provider-parameter-grammar) -and returns ordinary Go values. Integrations enforce their flag's outer shape: -provider parameters require an object; configuration assignments accept a JSON -value after their pointer prefix. Keep numeric conversion and its policy comments -in one private helper behind that entry point. - -The separate module paths `go.maximumdirect.net/commandkit`, -`go.maximumdirect.net/ckconfig`, and `go.maximumdirect.net/ckprompt` cannot share -core's private `internal` packages. The public CLI parser is the deliberate -cross-module boundary; no public general-purpose numeric conversion API or -separately versioned numeric package is introduced. It must work in independently -built modules, not only in the local workspace. Exact naming is implementation work. - -### Ordered typed input composition - -Add a small typed binding-composition capability preserving occurrence order -across participating flags. Current `RepeatFlag` and `FlagValues.ApplyTo` group -values by binding, which cannot establish OD-2's text/file winner by command-line -order. Exercise alternating text/file flags and their aliases before finalizing -the core API. Keep parsing, presence, conversion errors, and invocation isolation -in core; integrations choose how ordered typed values form their request. - -Do not expose Cobra/pflag structures or reparse raw arguments in `ckprompt`. -Ordinary flag collections and scoped alias declarations keep their existing -APIs. This prerequisite adds only the ordering support those declarations lack. - -## Initial report implementation approach - -Use ordinary report structs/maps, standard JSON interpretation, the existing -`go.yaml.in/yaml/v4` encoder, and standard `text/template`. Share rendering across -the invocation and writer APIs. Start with built-in template functionality; add -helpers only for demonstrated report needs. No new output module, custom -serialization engine, public document model, or per-format report tree is needed. - -Prefer native report values or thin projections. Align YAML-only tags with the -agreed JSON contract where needed. Small path, snapshot, location, and duration -projections serve report meaning; cosmetic field rearrangement does not justify -mirroring entire upstream object graphs. Render inspection values, not engines, -mutable runtime configurations, or credential storage. Preserve selected -presence/redaction distinctions and use the explicit YAML input conversion. - -### Output implementation inventory - -Core's universal `--format` controls report submissions. All report submissions -accept every core format; handlers retain no format allowlists. Existing raw -output remains an explicit delivery path, not data that core guesses how to -parse or translate. Apply the existing visibility and failure lifecycle to both. - -| Output path | Implementation and format boundary | -| --- | --- | -| Core version report | Hand off version data and its ordinary text template to the shared API. | -| `config scopes`, `show`, `sources`, `explain`, and `diff` | Use shared rendering for their report projections; remove local format selection and encoders. OD-4, OD-5, OD-8, and the aggregate-show decision own content. | -| `config validate`, including `--scope all` and `--details` | Submit one report for reached scopes, including failure evidence, under OD-6. | -| Prompt/profile/backend resource inspection | Hand the native inspection results directly to core under [resource inspection](#resource-inspection). | -| Requirements show/validate, catalogs, and prepared preview | Use shared report rendering and suitable thin projections or text templates. | -| Single smoke tests and `promptkit test all` | Preserve native evidence and the aggregate test list in one report submission, including partial results and errors. | -| Maintained application-owned command example | Demonstrate report handoff, optional template, and universal formats without a local format switch. | -| Help and usage | Keep the existing help/usage text path; the report format flag does not serialize help text. | -| Warnings, progress, deferred diagnostics, and terminal failures | Keep existing diagnostic presentation and destinations; report format does not change diagnostic content or channels. | -| Shell-completion scripts/protocol output and caller-selected raw writes | Preserve raw output required by the receiving shell or caller; do not wrap or encode it as a report. | - -Audit each listed path during implementation and remove obsolete format bindings and -format-specific helpers. Verify unknown format handling before domain work and -collision handling for the core-owned flag. Report aggregation belongs to each -integration; core does not gain a generic streaming-document framework. Beta -feedback should guide exact layouts; avoid tests that freeze incidental spacing -or field order. - -## Implementation plan - -The [staged implementation plan](implementation.md) owns ordered steps, selected -API designs, affected code, focused verification, module release handoffs, and -final independent-module validation. This feature roadmap owns target behavior, -operator intent, and the decisions below. Implementation status is recorded in -the plan; the checklist here defines the target acceptance boundaries. - -## Validation and completion checklist - -Select focused boundary tests under the [testing policy](../policy/testing.md). -The ownership and Go-native policy work is complete in -[architecture.md](../policy/architecture.md#ownership-boundaries). The checks below -cover the completed implementation, documentation, and dependency validation. -The checklist concerns core reporting and adapter/CLI behavior; it does not ask -CommandKit to retest PromptKit rendering, schema, namespace, or ConfigKit -resolution algorithms. -Default tests remain offline and independent of real credentials. - -The linked sections own behavior; these checks cover consequential boundaries -rather than prescribing one test per line or exact cosmetic snapshots. - -- [x] Public report/writer APIs, the CLI JSON parser, and ordered typed input - composition are documented. Maintained consumers exercise applicable APIs, and - both integrations build independently. Core has no integration dependency. -- [x] Universal format selection follows the agreed precedence and logical shapes. - Cover explicit choices, templates, scalars, empty/nonempty collections, null, - invalid formats before acquisition, flag collisions, and invocation isolation. - New formats require no handler changes or local allowlists. -- [x] JSON interpretation and explicit safe-YAML conversion preserve selected - field omissions, numeric values, type/presence/null/empty distinctions, sequence - order, and redaction. Unsupported serialization/conversion remains observable. - Ordinary strings are not implicitly parsed as YAML; mapping order is not a test - requirement. Do not substitute runtime configuration for inspection snapshots. -- [x] Templates receive original Go values and standard template behavior. - Explicit YAML/JSON does not execute a template; errors never trigger fallback. - Untemplated text follows the selected scalar/string-list or YAML rules. -- [x] Invocation and writer APIs share rendering; quiet mode, domain outcomes, - cause identity, cancellation, and presentation failures retain their agreed - lifecycle. Changing format does not change selected content or detail level. - Cover handler-selected submission after cancellation for acquired smoke and - aggregate-validation evidence, without imposing that behavior on ordinary - inspection or restarting canceled work. -- [x] Every path in the [output inventory](#output-implementation-inventory) is - reviewed. Remove obsolete per-command format plumbing and duplicate encoders; - preserve explicit raw output, help, and diagnostic boundaries. -- [x] `config show --scope all` submits the agreed scope-keyed mapping, including - a one-scope aggregate. Single-scope output remains unwrapped. Cover safe values, - fields named `scope`/`config`, and failure before combined display. -- [x] Dependency versions/checksums, attribution, and candidate notes match the - selected v0.20.0/ConfigKit releases. Canonical docs and examples describe the - selected contracts without legacy report/API variants or migration guidance. -- [x] Resource commands pass native prompt/profile/backend reports to core, - preserving returned message content, field omissions, and explicit - zero/false/empty values across formats. No per-field report mirror or backend - completion is added. Help distinguishes resource inspection, preparation, - credential references, and configuration provenance. -- [x] Backend inspection is independently optional, wired by `FromEngine`, and - uses the selected ID, applicable configuration selectors, and backend namespace. - Help/completion require no acquisition. Preserve native not-found errors, - cancellation, acquisition diagnostics, and delivery failures. Boundary tests - establish faithful forwarding and reporting, not upstream resolution rules. -- [x] Authentication response-limit evidence and smoke preparation errors retain - native unknown facts, supported causes, and outcomes, including no-report cases. - Smoke aggregation preserves ordered results and partial failure/cancellation - evidence in one report. Default tests need no live credentials or model calls. -- [x] OD-1 preview forwards the request, calls preparation once, and hands native - `PreparedRun` data to core unless a concrete presentation need warrants a small - projection. It makes no model call and retains no execution handle. Help explains - the prompt-ID argument, resource I/O, and rendered-content disclosure. -- [x] OD-2 collections work in standard and application-owned commands with their - own typed inputs. Preserve selected subsets, omission/empty/zero values, - upstream retry defaults, authoritative builders, and native map replacement. -- [x] CLI JSON parsing follows OD-2 for provider objects and configuration values. - Cover nested values, integer boundaries, decimal/exponent forms, range errors, - and ordinary float approximation. The private helper documents the policy and - its limits; no arbitrary-precision fallback or public numeric framework appears. -- [x] Canonical flags and scoped aliases follow OD-2; generated aliases cover - enabled/applicable bindings, preserve presence, and do not claim unrelated - application spellings. Canonical-only and convenient installation both work. -- [x] Ordered composition selects the last text/file occurrence for each input - name, including mixed aliases, while retaining literal empty text and file - references. Cover reordered/interleaved flags, conversion failures, and fresh - invocations. No prompt-input flags are added to smoke tests. -- [x] OD-3 namespace composition and applicability match the native boundary. - Cover defaults, explicit clearing, qualified IDs, and preservation of unrelated - defaults/catalog filters. Requirements help explains profile identity; cover - prompt-default fallback and short explicit profile selection without rewriting - configured references. Custom scoped loaders remain usable without the option. -- [x] The six-command configuration suite and optional provider capabilities - match installed help/completion metadata. Providers supply only enabled - capabilities; help, version, and capability discovery never trigger acquisition. -- [x] OD-4 explanation modes, filters, and bare-help behavior distinguish explicit - root selection, current/historical-only paths, and unavailable metadata. - Preserve native paths/history; do not assert upstream resolution algorithms. -- [x] OD-5 concise/detailed diff reuse the same native records and loads. Cover - additions/deletions, missing versus null, redaction/hidden changes, empty results, - atomic sequence changes, and delivery failure through the shared renderers. -- [x] OD-6 validation and failed-load source evidence preserve failure and - unavailable-versus-empty distinctions. Filters and known duplicate-message - coordination do not mask outcomes. Aggregate validation submits one document - with reached-scope evidence after stopping on acquisition failure/cancellation; - no unvisited scope is reported valid. Test the changed delivery timing and - separate operation/presentation failures without promising writer rollback. -- [x] OD-8 focused values and source selection respect capability availability, - one-scope path selection, absent versus null, unknown IDs, and acquisition - failure. Filters retain source references without changing validation outcomes. -- [x] OD-9 comparisons cover left-only, right-only, both/neither, and partially - specified sides, including repeated values and supplied state. Each side starts - independently; command-wide controls and the shared-state lifecycle remain - shared. Explicit-empty application selectors stay application-defined. -- [x] OD-10 assertion outcomes distinguish equality, changes, usage, and failures; - concealed changes count. Ordinary diff behavior and nonzero domain outcomes - survive presentation failure according to the reporting contract. -- [x] OD-11 parses only the selected assignment syntax, forwards explicit values - and safe labels to the correct side during loading, and preserves upstream - errors/provenance. Help documents unsupported `=` paths. No alternate input, - deduplication, conflict/precedence policy, or altered-value retry is added. -- [x] Maintained simple/composed consumers demonstrate the new CLI tasks and - failure workflow with deterministic fixtures. Code remains proportionate: - thin projections, one shared rendering implementation, and focused tests. -- [x] Update CLI/API contracts, release notes, and examples with the implementation, - including report framing, independent comparison selections, and validation - delivery timing. Keep contracts consistent with architecture policy and replace - obsolete native-YAML/document-order guidance in testing policy. The ADRs own - architectural rationale; these presentation and selector changes need no separate - successor records. Current documentation must match the landed scope. -- [x] Final independent-module and aligned-workspace suites pass with dependency - identities recorded. Deferred features remain outside this adoption. - -The [implementation plan](implementation.md) owns the concrete verification -sequence and commands. The [development guide](../development.md) and -[release procedure](../release.md) own routine toolchain, workspace, and release -setup. These adoption checks do not add permanent publication gates; a -dependency-only build does not establish the delivered CLI and reporting target. - -## Deferred work - -General execution, prepared handle lifecycle, sessions, and observer convenience -APIs remain application responsibilities. Persistent configuration editing, new -live probes, dynamic completion, and unrelated deferred proposals are not added -by this roadmap. -The [shared core API](#shared-core-report-output-prerequisite) targets text, -YAML, and JSON, with automatic availability of newly added core formats. -XML is removed from current consideration; Markdown is not selected for this -adoption. The three initial formats land together in the core feature release. -Transient acquisition overrides are included under OD-11. -Output-contract override and appended-message flags are deferred under OD-2 -and retained in -[future work](future.md#promptkit-inspection-and-selection-extensions). -Discovery tracing and secrets-directory bootstrap commands remain deferred: -the source inventory is not a trace of rejected search candidates, and bootstrap -performs application startup effects. - -## Open Decisions - -All numbered decisions are resolved for this adoption and retain their numbers -for reference. OD numbers are local to this roadmap, not the retired adoption -documents. The core prerequisite sections above own shared reporting and input -mechanics. Concrete API signatures, typed binding composition, loader wiring, flag -collision handling, and integration-owned projections are selected in the -[implementation plan](implementation.md), not unresolved product scope. Resource -reports use the native upstream fields selected under [resource inspection](#resource-inspection). - -### OD-1: Preview command and report presentation - -**Agreed:** use `promptkit show prepared PROMPT_ID` with the native `PreparedRun` -handed directly to core. Its existing JSON serialization fields cover the selected -report content. Introduce a small projection only for a concrete presentation -requirement; do not maintain a parallel report structure merely to copy those -fields. The structured mapping, without a dedicated text -template, selects YAML through core's automatic policy. Universal format choices -and automatic selection supersede both the earlier YAML-only restriction and -the command-specific default proposal. The argument names -the prompt to prepare, not a saved prepared object. A single native preparation -supplies both validation and preview evidence. - -The command sits beside [resource inspection](#resource-inspection) and emphasizes -that the report contains resolved settings and rendered content. Use help wording -such as: -"Prepare a prompt request and show the resulting messages and settings without -calling the model." - -Document resource I/O and rendered content disclosure directly in help and CLI -guidance. The report is an inspection snapshot, not a saved execution handle or -a guarantee that later execution uses the same snapshot or succeeds. Core's -YAML renderer also supplies explicit `--format text` output without requiring a -dedicated preview template; a specialized template is not required for initial delivery. - -### OD-2: Request controls and provider-parameter grammar - -**Agreed:** execution flags are public reusable CLI collections owned by -`ckprompt`, available to standard and application-owned commands. Collections -and aliases use existing declarations; JSON parsing and cross-flag ordering use -the [core input prerequisites](#shared-core-cli-input-prerequisites). Give -validation and preview the applicable execution controls already on smoke tests, -and add a singleton `--llm-extra-params JSON` object option to all three. -Use native whole-map replacement, including native behavior for -empty maps. The single-object form is selected over repeated key assignments. - -**Agreed CLI JSON number policy:** pass ordinary Go numeric values to PromptKit -and to ConfigKit for the configuration overrides selected in OD-11. -Classify numbers by their written JSON syntax, not by whether their mathematical -value could be an integer: - -- Integer syntax (no decimal point or exponent) becomes `int64`. Nonnegative - values above its range become `uint64` when representable. Reject integers - outside those ranges with a clear input error; do not fall back to floating point. -- Decimal or exponent syntax becomes `float64`: `42.0` and `1e3` remain floating - point even though their mathematical values are whole numbers. Accept ordinary - floating-point approximation; exact decimal representation is not required. - Report numeric range errors through the existing input-error path. -- Apply the same rules recursively inside JSON objects and arrays, preserving - other JSON value types. Decode with the standard library's `UseNumber` to avoid - premature floating-point conversion, then convert the temporary `json.Number` - values before handing parsed values to either upstream library. - -Keep this in one small, centralized internal helper dedicated to CLI JSON input. -Use standard Go numeric parsing; no arbitrary-precision fallback, general-purpose -number conversion package, public numeric conversion API, or extensible numeric -framework is selected. This applies the -[Go types and facilities policy](../policy/architecture.md#go-types-and-facilities) -to these CLI inputs: accept the selected types' precision and range without -alternate numeric representations. - -**Required implementation comments:** document the syntax-based type selection, -the `int64`/`uint64`/`float64` choices, accepted floating-point approximation, -range-error behavior, and the rationale for this narrow boundary beside the -helper. The comments must make clear that ordinary Go numeric limits are an -intentional policy, not a missing feature to work around later. - -This policy governs parsed CLI provider parameters and configuration override -values, not application-supplied runtime values or core report serialization. -The [public CLI parsing boundary](#public-cli-json-parsing-boundary) shares this -policy across modules while retaining private numeric conversion. -Reusing number conversion does not unify the libraries' different override -semantics or introduce a general-purpose conversion facility. - -Retain the authoritative-builder rule: standard flags seed a request, and an -application builder can return its complete replacement. Do not reapply CLI -values after the builder returns. - -**Agreed naming and aliases:** use `--llm-` canonical names throughout the -reusable request-control family. Standard `promptkit` commands also accept the -unprefixed convenience spellings wherever the corresponding flag applies. -Application-owned commands receive canonical names from the reusable collections; -applications may deliberately install convenience aliases on their own commands. - -| Canonical flag | Convenience alias within applicable `promptkit` commands | -| --- | --- | -| `--llm-endpoint` | `--endpoint` | -| `--llm-model` | `--model` | -| `--llm-temperature` | `--temperature` | -| `--llm-max-tokens` | `--max-tokens` | -| `--llm-top-p` | `--top-p` | -| `--llm-timeout-seconds` | `--timeout-seconds` | -| `--llm-service-tier` | `--service-tier` | -| `--llm-reasoning-effort` | `--reasoning-effort` | -| `--llm-api-key-env` | `--api-key-env` | -| `--llm-transient-retries` | `--transient-retries` | -| `--llm-extra-params` | `--extra-params` | -| `--llm-backend` | `--backend` | -| `--llm-profile` | `--profile` | -| `--llm-prompt` | `--prompt` | -| `--llm-session-id` | `--session-id` | -| `--llm-var` | `--var` | -| `--llm-input-text NAME=TEXT` | `--input-text`, `--llm-input`, `--input` | -| `--llm-input-file NAME=PATH` | `--input-file` | - -Retain existing value syntax and units, including integer timeout seconds. -The input naming and content changes are specified below. Commands taking a -positional prompt ID retain that argument; this naming decision does not add a redundant prompt flag. Execution, -resource-selection, and request-input collections may remain separately -composable. Namespace controls remain subject to OD-3. - -**Agreed assembly approach:** keep alias generation in `ckprompt`; alias -assembly requires no core upgrade. Define each flag-to-alias relationship once -and generate existing `FlagAliasFor` routing declarations from the flags selected -for each enabled canonical command. Do not maintain a separate hand-written matrix of -all command/flag combinations. Aliases target the original flag binding rather -than introducing duplicate bindings. Both spellings retain core parsing, -presence, and occurrence-order behavior. - -Offer a convenient collection containing the command family and its scoped -routing declarations, using existing `[]commandkit.Declaration` installation. -Keep `ckprompt.Command(suite)` available for canonical commands without the -convenience aliases. Exact helper names remain implementation choices. Generate -aliases only for enabled commands and applicable flags; do not install -application-wide aliases or make consumers reproduce the command/flag matrix. -Applications can install selected aliases on their own commands through the -existing core API. Subtree alias scopes and a new core declaration-bundle type -are not part of this adoption. - -Help should identify canonical names and their applicable aliases using current -core presentation. Update implementation, examples, help, and documentation -together. Canonical-only installation does not supply convenience aliases. - -**Agreed input forms:** include literal text alongside file input for -`promptkit requirements validate` and `promptkit show prepared`. The concrete -operator task is preparing one selected prompt with a short, disposable sample -without creating a fixture file. File inputs remain useful for substantial -content and repeatable artifacts. These operations make no model call and do -not establish model-output quality or application-workflow success. Assess -usefulness within these standard commands; speculative applicability to -multi-prompt application workflows is not a reason to add flags. - -Use the explicit canonical pair `--llm-input-text NAME=TEXT` and -`--llm-input-file NAME=PATH`. The scoped aliases in the table include both -`--input` and `--llm-input` for literal text. They route to the original text -binding with the same parsing, presence, and occurrence-order behavior. -`--input` denotes literal text; file bindings use the explicit file form. -Do not infer file access from literal content that resembles a path. - -Provide repeatable named bindings, splitting at the first `=` and preserving -literal content, including explicit empty text, through native `Inline` inputs. -File bindings continue to use native `File` references. Keep the canonical -forms available through reusable request-input collections; application commands -choose whether these bindings fit their workflow and may opt into aliases. -None of these aliases is application-wide by default. Do not add prompt-input -flags to smoke tests, which use their own diagnostic content. - -**Agreed input precedence:** the last command-line occurrence for a given input -name wins across text and file bindings, including every alias. Implementation -must preserve actual occurrence order rather than applying one flag collection -after the other in a fixed order. Use the core -[ordered typed input composition](#ordered-typed-input-composition) prerequisite; -independent flag binding alone does not supply this behavior. - -**Deferred output-contract overrides:** no CLI override is included in this -adoption. Retain the candidate in -[future work](future.md#promptkit-inspection-and-selection-extensions); -existing configuration and application builders remain available. - -**Deferred appended-message flags:** no CLI message-appending option is included -in this adoption. The potential standard-command task is reproducing a request -with application-added messages for preparation validation or preview. Revisit -when that is a demonstrated operator requirement; ordinary named inputs remain -available for inspecting prompt definitions with concrete content. Retain the -candidate in [future work](future.md#promptkit-inspection-and-selection-extensions). -No message-file format, flag syntax, or role-selection interface is selected. -Native application-supplied appended messages remain part of prepared-request -inspection; deferring flags does not remove that report evidence. No -general-purpose request-building API follows from these CLI choices. - -### OD-3: Namespace flags and loader defaults - -**Agreed:** make the standard namespace selectors opt-in with explicit -application-supplied defaults for prompts, profiles, and backends in the suite. -`ckprompt` combines those defaults with the supplied CLI fields, then applies -one native `WithNamespaces` call. Loaders using this option leave namespace -default selection to that adapter rather than relying on hidden engine-view -state. Without the option, applications control namespace selection in their -loaders. - -Omitting a selector preserves its declared default. Supplying a namespace -replaces that default for the invocation; supplying an explicitly empty value -clears it. Each resource type is independent. For example, overriding the -prompt namespace must preserve the declared profile and backend defaults. -Qualified resource IDs pass through unchanged. Catalog namespace filters remain -separate from these resource-resolution defaults. - -The standard option owns composition instead of requiring an application -callback to merge every selection. Applications needing custom namespace -selection can retain their own loading behavior without enabling the option. - -**Agreed names:** - -| Canonical selector | Scoped alias within applicable `promptkit` commands | -| --- | --- | -| `--llm-prompt-namespace` | `--prompt-namespace` | -| `--llm-profile-namespace` | `--profile-namespace` | -| `--llm-backend-namespace` | `--backend-namespace` | - -**Agreed applicability:** install only namespace selectors used by the operation -when the application enables the standard namespace option. - -| Operation | Resource-resolution namespace selectors | -| --- | --- | -| `promptkit show prompt` | Prompt | -| `promptkit show profile` | Profile | -| `promptkit show backend` | Backend | -| `promptkit requirements show` | Prompt and profile | -| `promptkit requirements validate` | Prompt, profile, and backend | -| `promptkit show prepared` | Prompt, profile, and backend | -| `promptkit test KIND`, including `all` | Prompt, profile, and backend | -| Resource catalogs | None; retain existing namespace filters | -| Configuration inspection | None; configuration inspection remains global within the selected configuration scope | - -Verify this table against the native calls during implementation. Do not install -a selector for symmetry when an operation cannot use it. Exact public helper -signatures remain implementation choices. - -**Agreed requirements-inspection behavior:** retain optional profile selection -and the profile namespace selector. In released PromptKit v0.20.0, requirements -inspection selects and verifies a profile identity, using the explicit profile -or the prompt's default, and includes that identity in the report. It fails when -neither supplies a profile or the selected profile does not exist. The profile -need not be execution-ready or have working credentials. - -The selected profile does not change the discovered prompt inputs or variables; -analysis uses the captured prompt templates, supplied variables, and session -context. Help must explain that profile selection establishes the reported -identity, not a different set of prompt requirements. The profile namespace -qualifies explicitly supplied short profile IDs; it does not rewrite the prompt's -configured default reference. Preserve this released upstream behavior without -adding a CommandKit workaround for profile-independent requirements inspection. - -### OD-4: Configuration path and metadata presentation - -**Agreed placement:** path discovery is part of `config explain`; no separate -path or metadata command will be added in this roadmap. - -**Agreed mode selection:** bare `config explain` displays command help as a -successful help request. Help explains that an operation requires either -`--list` to discover paths or `--path POINTER` to explain a selected path. This -makes both capabilities visible instead of implicitly choosing discovery. - -- Neither mode selected: show help, with success on successful help delivery. -- `--list` selected: discover configuration paths. -- `--path` supplied: explain that path. -- Both modes selected: report a usage error. - -Track path presence separately from its value: explicit `--path ""` selects -the root explanation, not help. This deliberately replaces the current -missing-path usage error; automatic discovery on a bare invocation is not -selected. - -**Agreed initial presentation:** supply a compact text discovery template, which -core selects automatically when no format is requested. Explicit alternatives -use core's universal `--format`. Operate on one scope at a time. -List current effective paths by default; `--historical` adds historical-only paths -rather than selecting only removed paths. Show path, current/historical-only -presence, and available explicitness. Do not equate non-explicit values with -application defaults or historical-only metadata with explicitness false. - -Use `--under POINTER` to narrow listing to a subtree and -`--explicit=true|false` to select current explicitness. Omitting explicitness -filtering includes both states and, when requested, historical-only entries; -historical-only entries do not match either current explicitness value. Apply -subtree filtering to parsed paths, not textual prefixes. These filters and -`--historical` belong to listing mode; `--path` continues to select detailed -explanation, including its available metadata and history. - -Keep values and change history out of the compact listing. Include useful field -metadata in detailed explanation without repeating existing evidence. If a -provider cannot supply discovery metadata, report that capability as unavailable -rather than presenting an empty configuration; its existing path-specific -explanation remains usable. These are sufficient starting choices for the MVP; -exact field layout and mode-specific error wording can be decided in code and -reviewed with concrete examples. - -### OD-5: Detailed comparison selection and shape - -**Agreed:** retain the existing concise additions/changes/deletions report as -the default for `config diff`, and add optional `--details` for investigating -changes. The default serves human operators who need a quick overview. - -The detailed mode should help an operator compare old and new values, -distinguish absence from explicit null, and understand concealed changes even -when the displayed safe snapshots look equal. Present native paths, left/right -snapshots, presence, redaction, and hidden-change evidence in readable YAML. - -**Agreed initial layout:** one entry per changed path in a scope-labeled YAML -report, with before/after snapshots rather than expanded versions of the three -summary categories. Display snapshot values as YAML values, preserving explicit -presence so missing and null remain distinct. Show redaction and concealed-change -annotations where relevant; omission of an optional annotation has a defined -meaning and never relies on recognizing a marker-looking string. Prefer ordinary -Go fields and serialization tags to custom omission logic. An empty comparison -has an explicit empty difference list. Both concise and detailed comparison -hand off structured mappings without a text template; core's automatic policy -selects YAML. Universal format choices supersede the earlier YAML-only detailed -restriction. The same selected comparison evidence is handed to core in every -format; explicit text without a template reuses core's YAML renderer. - -Keep the projection close to native report values, using the -[shared reporting approach](#initial-report-implementation-approach) rather than -extensive translation for cosmetic layout. Exact field names are implementation -choices for the initial release and can evolve with beta feedback. - -Keep implementation localized to detail selection and a report projection, -with focused boundary tests, help, and examples. The existing `Scope.Compare` -contract and both native adapters already return the required difference -records. Reuse that data and existing safe-snapshot decoding; no new comparison -callback, additional load, or comparison algorithm is required. Use the shared -core report output capability; detailed comparison needs no domain-specific core -API. A side-by-side terminal display is not part of this adoption. Comparison -exit status follows OD-10. - -### OD-6: Failure evidence and structured diagnostic delivery - -**Agreed placement:** structured configuration diagnostics are part of -`config validate`; there will be no separate diagnostics command. Source -inventory on failure remains part of `config sources`. - -**Agreed:** add `config validate --details`, consistent with the optional detail -mode on `config diff`. Retain concise validation by default, including its -ordinary warning and error reporting. Detailed mode reports available native -diagnostic records and source references alongside the validation result. The -purpose is to help a human operator locate and investigate configuration -problems; it does not introduce new validation rules. Changing the output format -does not implicitly enable the additional detail. - -Preserve available evidence when loading fails: `config validate --details` -reports diagnostic findings and relevant source references, and `config sources` -reports acquired source inventory. These describe the current invocation, not a -previous failed command. Keep the original failure and its supported cause -identity; successfully displaying evidence must not turn failure into success. -A failed load does not imply an effective configuration is available. - -Build optional `ckconfig` evidence facets that can accompany an acquisition -error. Unlike detailed comparison, the existing adapters need to carry additional -structured evidence through to reporting. Use current core reporting and outcome -handling; no generic cross-family diagnostics framework is required. - -**Agreed initial presentation:** supply a detailed validation text template, -which core selects automatically unless the operator requests another format. -The template begins with scope and outcome, then shows readable findings with their available -messages, severities, codes, configuration paths, and source locations. Place -useful locations near messages; -YAML may use a source legend shared by multiple findings. - -Use repeatable `--severity` and `--code` filters in detailed mode. Multiple values -within a filter match any selected value; different filters narrow results -together. Filtering never changes the validation outcome. Distinguish no native -findings, no findings matching the filters, and unavailable structured evidence. -Keep referenced sources needed to interpret selected findings. - -Avoid presenting a finding both in the detailed report and as a duplicate -ordinary warning when the records have a known relationship. Do not deduplicate -by guessing from message text. Preserve unrelated messages and the terminal -failure explanation. Keep this coordination within the integration rather than -introducing a general diagnostics framework. - -Structured results use the result stream and ordinary messages use the -diagnostic stream. Preserve report-delivery failures separately from the original -operation failure through existing outcome handling. - -**Agreed aggregate delivery:** for `config validate --scope all`, collect results -for the scopes reached and submit one report after acquisition completes or -stops. Stop at the first acquisition failure or cancellation; retain completed-scope -results and available evidence from the failing scope. Do not claim unvisited scopes -were validated. Apply the same aggregation to concise and detailed modes, using -one ordinary report value and the shared renderers, including one JSON document. - -The validation handler submits that acquired evidence even when cancellation -stopped acquisition, following the -[shared reporting cancellation boundary](#agreed-format-independent-reporting-operation). -Do not reuse an ordinary inspection helper's cancellation guard to suppress this -report. Preserve the cancellation outcome alongside any presentation failure. - -This deliberately changes delivery timing: scope results are no longer written -one at a time during acquisition. Output failures are observed after acquisition -has stopped and cannot prevent already-completed loads. Preserve the original -operation failure and separate presentation failure under the existing outcome -rules. This replaces the old output-failure stopping behavior; it does not add -exhaustive validation, whole-invocation buffering, or writer rollback. Diagnostics -retain their existing lifecycle. Update the canonical validation contract and -its focused failure tests when this lands. - -### OD-7: Module release and interim workspace coordination - -**Agreed:** complete the core reporting/input prerequisites and planned -integration work together in the selected feature delivery. -Prepare the core release supplying those APIs, then a new ckconfig minor -release for the shared API/CLI features, and update the still-unpublished -ckprompt candidate. Both integrations must require a core version supplying the -new API, and ckprompt must require the ckconfig version supplying the shared -work. Confirm candidate status and available versions under the release -procedure before choosing versions. - -Use the ignored aligned workspace during joint development. Workspace success -does not establish independent integration correctness with old core or ckconfig -requirements. Before final independent validation, pin released dependency -versions supplying the APIs and validate all three independent modules and the -aligned workspace. Dependency release order is core, ckconfig, then ckprompt. -Publication remains a separate action requiring authorization; this decision -does not authorize publication. - -### OD-8: Focused configuration reports and filtering - -**Agreed:** add `config show --path POINTER` and -`config sources --source-id ID`; add subtree/explicitness filters to -`config explain --list` and severity/code filters to `config validate --details`. -Keep reports unfiltered by default. The purpose is to reduce noise for a human -operator investigating a known part of the configuration. - -`config show` hands off the selected logical configuration value without a text -template. Core selects from its shape: a mapping yields YAML, while a selected -string yields text. Explicit `--format yaml` renders the safe effective value as -YAML, without a snapshot wrapper containing presence/redaction/YAML fields or a -promise to preserve upstream formatting or mapping order. -All formats render the selected value through the shared representation. -Use the existing explanation capability to obtain the native snapshot. An absent -effective path or unknown source ID produces a clear operational failure. Explicitly present -null remains a valid value; historical-only paths are not effective values. -Path-selected display initially uses one scope, while whole-document -`--scope all` uses the agreed [scope-keyed mapping](#agreed-aggregate-configuration-presentation). - -Filters change presentation, not validation outcomes. Keep source references -needed to interpret the selected findings. Apply subtree filtering to parsed -paths; distinguish unavailable current metadata on historical-only paths from -an effective value that was not explicitly supplied. - -**Selected filter grammar:** OD-4 records discovery filters and OD-6 records -diagnostic filters. Exact report field layout and remaining edge-case messages -are implementation choices for the MVP. No additional snapshot-wrapper report -or aggregate path-selected display is selected for this adoption. - -### OD-9: Independent comparison selector bindings - -**Agreed comparison model:** initialize the left and right sides independently -from the configuration the application ordinarily loads without CLI configuration -selections or overrides. Ordinary loading retains application discovery, files, -defaults, environment handling, and resolution; it does not mean an empty or -defaults-only configuration. - -Apply each side's explicitly supplied values only to that side: - -- `--config`, `--overlay`, application configuration selectors, and `--set` - affect the left side. -- Their declared `--against-*` counterparts affect the right side. -- Every omitted field retains that side's ordinary application default and - unsupplied state. Never copy the opposite side's value or supplied state, - even when other fields on the right are explicitly supplied. -- Repeatable selectors follow their declared typed binding behavior on their - own side. Left-side elements are never copied into the right collection. -- Command-wide controls such as `--scope`, `--format`, `--details`, and `--check` - govern the comparison as a whole and remain outside this separation. - -| Invocation after `app config diff` | Left selection | Right selection | -| --- | --- | --- | -| `--config candidate.yml` | `candidate.yml` | Ordinary configuration | -| `--config before.yml --against-config after.yml` | `before.yml` | `after.yml` | -| `--config base.yml --against-overlay experimental` | `base.yml` | Ordinary configuration with the selected overlay | -| `--config base.yml --against-config base.yml --against-overlay experimental` | `base.yml` | `base.yml` with the selected overlay | -| `--against-config candidate.yml` | Ordinary configuration | `candidate.yml` | -| No side-specific flags | Ordinary configuration | Ordinary configuration | - -The examples retain normal application interpretation of file and overlay -selectors. Explicitly selecting the same nondefault input on both sides requires -supplying it on both sides. Equal selections remain allowed and do not skip -acquisition or comparison. - -Applications declare which domain selectors support right-side values, with -explicit metadata for their `--against-*` spellings. Do not generate comparison -flags for every application option automatically. A configuration selector -without a right-side binding still affects only the left when supplied; it is -not implicitly shared. Domain parsing stays in declared typed bindings; no -generic selector language is introduced. Retain the two input preparations and -checks, one shared invocation state, and existing provider lifecycle. - -This deliberately replaces the current inheritance model, including existing -config/overlay behavior and shared application selectors. Update CLI/API contracts -and examples when implementation lands. The input/state ownership in -[ADR 0001](../adr/0001-command-dispatch-and-inputs.md) remains unchanged; selector -policy does not need a separate successor ADR. Exact helper signatures and flag -collision handling remain implementation design tasks. - -**Agreed collection scope:** leave explicit-empty selection for application-defined -repeatable selectors to application-declared bindings in this release. Omission -retains that side's ordinary collection; an empty string element is not implicitly -an empty collection. No additional standard collection-clearing flags, including -the earlier proposed `--against-clear-*` forms, are selected. - -Actual configuration lists supported by OD-11 can be replaced with an empty list -using `--set /path=[]` or `--against-set /path=[]` on the corresponding side, -subject to upstream path and schema rules. This does not necessarily express -empty selection for an application selector that controls which sources load. -Retain general collection-clearing support as a -[future candidate](future.md#comparison-extensions) pending a concrete consumer -need. OD-9 requires no further operator-policy decision for this adoption. - -### OD-10: Comparison assertion outcomes - -**Agreed:** add opt-in `--check`, retaining normal report delivery and ordinary -diff behavior when omitted. Under assertion mode, use status `0` for equality, -`3` for differences, `2` for usage errors, and `1` for operational failures. -This distinguishes a successful comparison that found differences from a -comparison that could not run. Ordinary diff remains successful when it finds -differences. - -Base the difference outcome on native records, including concealed changes, -not equality of the displayed safe values. Apply existing reporting outcome -rules, including preservation of a nonzero domain outcome when presentation -also fails; callers can inspect the separate presentation evidence. Document -and test that interaction explicitly. These are selected future behaviors, -not claims about the currently implemented CLI. - -### OD-11: Transient configuration overrides - -**Agreed scope:** include a declared, opt-in override capability for standard -configuration commands, with repeatable `--set POINTER=JSON` values passed to -application acquisition as native ConfigKit overrides. This enables validation, -inspection, and comparison of temporary settings through consistent CLI syntax. -Providers that do not accept overrides retain their existing operations. No -source file is edited, and no general application-internal convenience API is -required. Supply parsed records during the normal configuration load, like any -other explicitly supplied CLI overrides; the generic adapter cannot inject -them into an arbitrary loader after the load has completed. - -**Agreed input syntax:** support only `POINTER=JSON`, split at the first `=`. -Paths containing `=` are unsupported by `--set` and `--against-set`. Document -this limitation in help; do not add alternate JSON-record syntax, an escaping -scheme, or an override-file option. This limits these flags rather than banning -such keys elsewhere in configuration. The JSON value may itself contain `=`. - -**Agreed loading boundary:** CommandKit parses supplied assignments, preserves -explicit values and safe source labels, and passes the records to the appropriate -loader and comparison side. ConfigKit owns path validity, duplicate/overlap -handling, precedence, resolution, and validation. If the normal load returns a -ConfigKit error, preserve and report it through the existing diagnostic/outcome -path. CommandKit does not deduplicate records, resolve conflicts, invent a -combination or precedence policy for application-owned overrides, or retry with -altered values. Application loading retains its existing responsibilities. -Exact loader signatures and wiring remain implementation design tasks. - -**Agreed numeric conversion:** both assignment flags use the -[OD-2 numeric policy](#od-2-request-controls-and-provider-parameter-grammar), -including nested values, through core's public CLI JSON parser. ConfigKit receives -ordinary Go values; the shared numeric helper and policy comments remain private. - -**Agreed comparison behavior:** `--set` supplies override records only to the -left side; `--against-set` supplies records only to the right. Each side starts -from its ordinary configuration under OD-9. Omission supplies no CLI override -records for that side; it never inherits records from the other side. Normal -application-owned overrides are part of ordinary loading and are not erased by -omitting these flags. - -For example, `config diff --set /workers=4` compares the left configuration with -that override against the ordinary right configuration. Adding -`--against-set /workers=8` explicitly overrides the right configuration as well. -Repeat the same `--set` assignments as `--against-set` assignments when both -sides should use them. There is no shared CLI override baseline and no -`--against-clear-set` flag is needed to undo inheritance. - -Implement the selected handoff without reimplementing upstream behavior: - -- Split at the first `=`; JSON supplies typed null, boolean, string, numeric, - array, and object values, with the agreed numeric policy above. -- Forward explicit records only, with safe display labels such as `--set`, - never raw value-bearing arguments as provenance labels. Preserve native - duplicate/overlap handling rather than silently collapsing assignments. -- Let ConfigKit enforce its released mapping-path constraints, including - root/index and schema-version restrictions, without introducing a generic - patch language. Empty, false, zero, and null remain intentional supplied values. -- Reflect native CLI origins and subsequent resolution in existing reports. - Test CommandKit parsing, forwarding, and outcome/report adaptation, leaving - ConfigKit's override algorithm to its own tests. - -Application-specific typed flags remain available, but are not a substitute for -the selected standard CLI capability. No persistent configuration mutation is -authorized by this decision. OD-11 requires no further operator-policy decision -for this adoption.