# Shared report output, PromptKit v0.19.0 adoption, and ConfigKit operator CLI Status: proposed roadmap for review. Scope is agreed in principle; implementation has not started. Command spellings, report designs, and API changes below are recommendations except where explicitly recorded as agreed below. Accepted report formats are an initial implementation target; practical beta feedback will guide later refinements rather than requiring exhaustive layout design now. ## Ownership principles Applications and integration handlers choose the operation and report content; CommandKit core supplies the shared CLI mechanics. Integrated libraries retain ownership of their domain behavior. | Area | CommandKit Owns | CommandKit Does Not Own | | --- | --- | --- | | **CLI output — core** | Format selection, serialization, template execution, and output delivery | Choosing report content or detail level; authoring application-specific text templates | | **PromptKit/ConfigKit integrations** | Standard commands, flags, and report content that expose useful operator tasks through upstream public APIs | Helpers or convenience interfaces for application-internal use of upstream APIs | | **CLI inputs** | CLI syntax, parsing, typed bindings, presence tracking, and usage diagnostics | Application business rules or upstream domain-validation semantics | | **Upstream behavior** | Selecting and invoking supported capabilities, adapting their results, and preserving their meaning | Reimplementing upstream configuration resolution, prompt preparation, validation, or other domain algorithms | | **Outcomes and errors — core** | Carrying and presenting selected outcomes; handling CommandKit's own parsing, rendering, and delivery failures | Deciding application recovery policy or terminating the process | | **Application lifecycle** | Command dispatch and invocation reporting lifecycle | Application startup, engine construction, credential provisioning, signal handling, or long-lived application state | These agreed principles are recorded here for eventual incorporation into [architecture.md](../policy/architecture.md). ## Purpose and ownership Adopt released PromptKit v0.19.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 a new public core reporting capability as a prerequisite 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. The [architecture policy](../policy/architecture.md), [optional-module decision](../adr/0010-optional-integration-modules.md), and [reporting decision](../adr/0014-invocation-reporting.md) govern implementation. The [CLI reference](../cli.md) and public GoDoc remain the owners of implemented contracts. This roadmap selects work for review, not new guarantees about upstream behavior or permanent limits on future features. ## Baseline and released evidence Repository baseline: `0b4e47c4206e323f7c5d5ec3f357494dd23008b2`. The completed v0.18.0 adoption is not reopened. | Component | Current baseline | Target | | --- | --- | --- | | Core | `go.maximumdirect.net/commandkit`; Go 1.26.0 minimum | Public report output API with universal format choices and automatic selection; text/YAML/JSON land together as a prerequisite. Flag collections and scoped aliases still use existing core 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.19.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.19.0`, commit `4f3212bfb6c1f37f43d50715c2cedc1d43203064`. 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/4f3212bfb6c1f37f43d50715c2cedc1d43203064/docs/releases/v0.19.0.md), [request and report types](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/4f3212bfb6c1f37f43d50715c2cedc1d43203064/types.go), [engine API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/4f3212bfb6c1f37f43d50715c2cedc1d43203064/engine.go), [namespace API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/4f3212bfb6c1f37f43d50715c2cedc1d43203064/namespaces.go), [configuration inspection API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/4f3212bfb6c1f37f43d50715c2cedc1d43203064/configuration_inspection.go), and [smoke API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/4f3212bfb6c1f37f43d50715c2cedc1d43203064/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 original adoption tasks remain included: 1. Update the dependency, checksums, attribution, and unpublished candidate note. 2. Document all three upstream compatibility changes and correct credential inspection wording. 3. Cover the new authentication reason and corrected smoke preparation-error propagation at CommandKit's boundary. 4. Validate the final independent modules and aligned workspace. Add the following operator capabilities. Syntax is illustrative unless selected in the decisions at the end of this document. | Operator task | Proposed CLI | Owning module and report | | --- | --- | --- | | 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. Unusual pointer keys, loader composition, and supplemental input grammar remain to be finalized. Comparison overrides follow OD-9's independent-side model: `--set` affects only the left side and `--against-set` only the right. ### Compatibility and native semantics Document these v0.19.0 changes for consumers constructing engines and inputs: - Successful custom `ArtifactReader.Read` transfers ownership of its returned artifact and mutable body storage. Readers retaining scratch storage must supply independent returned storage and stop mutating returned aliases. - `ProfileSource` and `BackendSource` provider maps now use ConfigKit's native recursive Mapping forms: built-in scalar values, `[]any`, and `map[string]any`. Explain explicit conversion of `json.Number` and typed containers. Runtime execution overrides have a separate accepted-value contract; do not impose configuration-source restrictions on their flags. - Local-validation and structured-output schemas must be self-contained. External resources and filename-dependent base references fail preparation; internal references or explicit schema IDs supply the supported route. No configuration-format migration is required from v0.18.0. Correct the CLI description of `api_key_required`: it indicates a usable direct or environment credential requirement and can coexist with `api_key_env`. Neither field is evidence of current credential availability. The new authentication response-limit reason is factual evidence with unknown credential acceptance. Continue forwarding 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. ### Preview and request flags Expose preview as `promptkit show prepared PROMPT_ID`, using core's automatic selection and universal format choices, through an independently available capability alongside existing suite callbacks. The native adapter calls `Engine.Prepare` and projects its returned snapshot; a preliminary `ValidateRequest` call is unnecessary. Use existing typed selection, acquisition diagnostics, and invocation reporting patterns. Exact callback names and signatures follow the selected CLI design. Preview performs applicable resource I/O and rendering but no model call. Rendered and appended messages contain application content. Upstream excludes resolved credentials from prepared settings; that does not make the whole snapshot a redacted configuration report or a transferable execution handle. Expose the upstream snapshot evidence without implying later execution uses that exact snapshot or will succeed. Provide public, reusable typed execution-flag collections in `ckprompt`, defined once and used by smoke, validation, preview, and application-owned commands. The collections standardize flag names, help, parsing, completion hints, supplied-value tracking, and binding into native PromptKit request fields. Applications retain their own input structs, request construction, engine acquisition, execution, and outcomes. Reusing CLI declarations is within CommandKit's ownership boundary; it does not introduce runtime convenience APIs. Use the existing core `CommandSpec[I].Flags`, typed flag constructors, and `Supplied[T]`. A generic collection factory can accept destination accessors and return ordinary `[]commandkit.Flag[I]`. Direct binding is sufficient for ordinary use; existing [CaptureFlags and FlagValues.ApplyTo](../../flag_values.go) support deferred application or multiple destinations where needed. These flag collections require no core change or new core collection abstraction. Exact exported names and accessor signatures remain implementation design choices. Keep execution-target overrides and the request-level transient retry field distinct even when one convenient collection includes both. Preserve omission instead of imposing shared defaults: ordinary execution and smoke diagnostics have different native retry defaults. Preserve native explicit zero/empty values and whole-map replacement semantics. Support deliberate subsets for actual command needs while retaining common flag names and meanings, using a proportionate composition API. Keep parsing in CommandKit and domain validity in PromptKit. Existing application builders remain authoritative as agreed in OD-2. That decision also selects literal-text and file input bindings and defers output-contract overrides and appended-message controls. ### Namespace selection Design independent prompt, profile, and backend defaults together. Native `WithNamespaces` replaces all defaults on its new view; it has no partial-update semantics. Under the agreed OD-3 design, opt-in selectors combine explicitly declared suite defaults with supplied overrides; they do not infer defaults from a loader's engine view. Qualified IDs pass through native selection unchanged. Captured references, configuration inspection, and namespace/collection inventories retain their native meanings. Existing `--namespace`/`--all-namespaces` catalog filters continue to describe filtering. Install selectors according to the agreed applicability table in OD-3 and verify their use at the upstream call boundary. ### Shared configuration capabilities Extend `ckconfig` through optional capabilities so existing custom providers can keep their currently declared operations. Both `FromConfigKit` and `ckprompt.ConfigScope` should expose available native evidence. Do not require all providers to implement every new inspection mode. Providers lacking metadata or structured diagnostics retain their existing explanation/validation behavior; mode availability and help must reflect the capabilities supplied. For metadata, use `Metadata.HistoricalPaths`, `Lookup`, `IsExplicit`, and `History`. Enumeration covers observed paths, not all possible schema fields. Do not discard history because effective lookup fails. Existing explanation already reports current/historical values; add the missing discovery and explicitness within explanation discovery instead of reproducing upstream provenance logic. Preserve native list-index paths; do not silently reinterpret them as resource IDs. For optional detailed comparison, project the native `Difference` records already returned by `Scope.Compare`; retain the existing concise report by default. Keep snapshots and their presence/redaction fields together, including `HiddenChanged` when the safe values look equal. Reuse the same loading and comparison path for both presentations. Native sequence comparisons remain atomic; this work does not add element-level resource matching or a reloadable patch format. For failure investigation, retain `LoadError.Sources()` and `Diagnostics()` as evidence alongside the error. The current adapters and `config sources` failure path need changes, not just another renderer. Define an acquisition shape that distinguishes unavailable evidence from an available empty inventory. A failed load does not establish an effective configuration or metadata capability. Render available evidence through normal invocation reporting before terminal failure presentation. Keep the original load error and supported identity; successful report delivery must not convert failure to success. Preserve render/write failures separately through the current outcome machinery. Cover cancellation with partial evidence explicitly without promising interruption of an arbitrary writer or rollback of already-delivered bytes. OD-6 selects `config validate --details`; its interaction with ordinary diagnostic messages remains a presentation design task. Structured records describe that validation invocation, including a failed load; they are not a retrieval interface for an earlier command. Preserve the current aggregate validation stopping behavior unless deliberately revised; structured reporting alone does not promise exhaustive findings across scopes. ### Additional ConfigKit operator workflows **Focused effective display.** Use the effective snapshot from native `Explain(path)` for path-selected display. The ordinary whole-document path continues to use `WriteEffective`. A historical-only path can be explainable while lacking an effective value; distinguish that case from a present YAML null. Select the missing-value behavior, provider availability, and aggregate scope applicability under OD-8. Do not read mutable `Result.Config` or source files to reconstruct inspection values. **Source selection and report filters.** Select source IDs from the acquired inventory, preserving existing record fields and upstream ordering. Native `Source(id)` is a convenience, not an additional provider requirement. IDs are local to a load and do not guarantee the same source in a later acquisition. Apply subtree filtering to parsed configuration paths, not raw string prefixes that would confuse `/server` with `/server2`. Specify explicitness filtering for historical-only paths without treating unavailable effective metadata as false. Diagnostic filters affect the presented records, not the underlying acquisition outcome; retain the source references needed to interpret selected records. **Independent comparison selections.** Extend the per-side typed-input design in [ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md), deliberately replacing its left-to-right inheritance and shared application-selector rules. Initialize each side from ordinary application defaults and apply only that side's explicitly supplied configuration selections and overrides under OD-9. Prepare and check both inputs before comparison and preserve the existing shared invocation state. Domain parsing, default interpretation, and loader caching remain with the application; the comparison provider still receives two selections. **Comparison assertions.** Base a difference outcome on native record presence, including hidden changes whose redacted snapshots look equal. Equal effective values can have different histories or explicitness. Comparison also does not detect changed credential bytes behind an unchanged secret reference. Use the agreed opt-in outcome and report-delivery behavior under OD-10; retain the current ordinary diff outcome. A load or comparison failure is not evidence of equality. **Transient overrides.** As agreed in OD-11, parse explicitly supplied CLI values into native `Override` records and pass them through a declared loader capability. ConfigKit owns override path validity, supported values, precedence, decoding, resolution, provenance, and validation. Its configuration overrides recursively overlay mappings and replace sequences; this differs from the PromptKit execution override's complete provider-map replacement. Do not reuse one grammar implementation in a way that erases that distinction. Source-load errors remain errors even if an 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; exact public names, signatures, and internal representation remain design work. ### 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. ### 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, record the deliberate replacement of [ADR 0007](../adr/0007-native-yaml-reports.md)'s native-writer and mapping-order requirements in a superseding ADR and update current contracts. Retain the accepted ADR's decision text as history. The aggregate presentation decision below also replaces its separate-document framing. 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 public preparation and handoff signatures and the small helper set remain implementation design tasks. 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: default_profile: standard ``` 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, supersede ADR 0007's ordered native-document framing and refine [ADR 0009](../adr/0009-configuration-scopes.md)'s combined-display ordering contract through a new ADR. This decision concerns aggregate display; it does not change scope discovery or acquisition ordering. ### Remaining core reporting implementation details Exact public signatures, reusable template preparation and helper functions, flag integration/collision handling, and replacement of existing format plumbing are implementation design tasks. 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. ## Initial report implementation approach Use the accepted OD-4 through OD-6 flags and formats as a practical starting point. Keep added code, report types, and translations proportionate. Beta feedback on actual reports should guide changes. Resolve the core design details above, then implement the agreed extension points without delaying delivery for exhaustive layout design or speculative additional renderers. The repository already uses `go.yaml.in/yaml/v4` and small Go-value-to-YAML writers in core and both integrations. Consolidate suitable report paths onto the new core API and share encoder configuration and representation helpers. Use the capability in core, both integrations, and a maintained application-owned command example. A separately versioned output module or custom serialization engine is not needed. Follow module release/dependency ordering under OD-7. Prefer handing off suitable native inspection/report values or a thin Go projection using the agreed JSON serialization conventions. Do not mirror a whole upstream object graph just to rename fields or rearrange equivalent data. Reuse small path, snapshot, location, and duration projections where they are genuinely needed. Core reuses the JSON contract across its serialization paths; migrate YAML-only report tags or provide a thin projection where necessary. Safe configuration YAML enters the ordinary Go-value path through core's explicit input conversion helper. Exceptions serve concrete report semantics: preserving absent/null/false/zero and empty collections, expressing paths and durations readably, projecting safe snapshot values, and retaining native redaction. Encode report/inspection values, not engines, mutable runtime configuration, or request credential storage. Preserve inspection data meaning and the concise diff and validation content selections. Integrations prepare those values and any text templates; core owns rendering. YAML input conversion feeds that same machinery without preserving source formatting or adding an integration-owned formatting pipeline. Separate content projection from format rendering and from invocation delivery. Use the existing Reporter and outcome lifecycle for delivery and failures. Text templates receive original Go values. Simple text output uses the logical report values directly, while structured text without a template delegates to the YAML renderer without a YAML encode/decode round trip. Do not force semantically different reports into one schema. Validate representative reports and meaningful adaptation boundaries, rather than freezing every incidental formatting detail in tests. ## Work sequence 1. **Confirm remaining implementation choices.** Use the accepted flags, report content, aggregate presentation, and automatic format policy as the MVP target. Specify the public API, reusable template helpers, and internal conversion design under the agreed JSON representation contract. Resolve outstanding acquisition/binding grammar and flag collisions; use concrete examples to review report details during implementation rather than reopening accepted scope. 2. **Implement shared core report output.** Deliver the agreed automatic format policy, universal `--format` selection, format-independent Reporter operation, writer-based API, and shared representation/encoding machinery. Deliver YAML encoding, text printing/templates, and JSON encoding together in the core feature release. Exercise the public API with core reporting and an application-owned command example, and consolidate suitable existing integration reports onto it. Cover the selected contracts and update their canonical documentation with the implementation. Complete this prerequisite before building the downstream additions; use the aligned workspace until the core release is available under OD-7. 3. **Adopt v0.19.0.** Update `integrations/ckprompt/go.mod` and `go.sum`, then [module attribution](../../integrations/ckprompt/docs/oss/attribution.md) against the released notices and source commit. Update the unpublished candidate note and affected canonical dependency/compatibility guidance. No core Go-minimum increase follows from this adoption. 4. **Implement request inspection and selection.** Add preview, literal-text input and renamed file-input flags, applicable override flags, provider-parameter input, and namespace selectors. Implement public `ckprompt` execution-flag collections on existing core bindings and reuse them in the standard commands. Generate scoped convenience aliases and provide a collection for installing the commands and routing declarations. Reuse the standard suite's lifecycle and preserve existing application adapter seams. Render suitable new reports through the shared core API. 5. **Implement shared configuration inspection.** Add discovery and metadata within `config explain`, structured diagnostics via `config validate --details`, detailed diff presentation, and source evidence on failure in `ckconfig`. Retain the six-command suite and wire native PromptKit facets through `ConfigScope`. Add focused effective display, source selection, and bounded metadata/diagnostic filters using those evidence capabilities. Extend typed comparison selection and add the agreed assertion outcome. Implement explicit override acquisition and comparison-side wiring under OD-11 as a separate reviewable unit. Use the shared core API under the initial report implementation approach. Keep boundary coverage with each change. 6. **Update operator and consumer documentation.** The CLI reference owns syntax, report schemas, availability, and outcomes; GoDoc owns callback and value contracts. Extend maintained simple/composed examples to demonstrate the new CLI tasks using local fixtures, without adding application-internal execution helpers. Record intentional compatibility effects in module notes. 7. **Align module dependencies and validate.** Prepare the core release needed by both integrations and the `ckconfig` release needed by `ckprompt`. Align requirements/checksums and complete the validation below. OD-7 addresses interim workspace development and dependency order. Publication and hosted delivery remain separate actions under the [release procedure](../release.md). ## Validation and completion checklist Select focused boundary tests under the [testing policy](../policy/testing.md). 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. - [ ] Public signatures and shared representation conventions are documented with implementation. - [ ] Core owns universal `--format` options, help, validation, and selection. Added core formats work with existing commands without refactoring or local allowlists. Unknown selections fail before acquisition, and selected formats do not leak between invocations. - [ ] Explicit operator selection overrides automatic selection. Without it, a text template selects text; otherwise core selects from the shared report shape. Cover scalars, nonempty string lists, mappings, mixed/nested lists, empty collections, and null. The initial API has no command format defaults. - [ ] Automatic selection uses the logical report after adaptation, once per complete report. Native YAML source strings are not mistaken for string configuration values. Focused configuration values follow the same rules. - [ ] Plain text, YAML, and JSON ship together; representative reports exercise shared representation and explicit selection across all three. - [ ] Text templates execute with standard `text/template` behavior against the original Go report value, retaining field names and types. JSON tags and custom JSON serialization do not rename, omit, or replace the template input. Explicit YAML/JSON output does not execute the text template. - [ ] Template syntax and execution failures remain observable errors; a failing template never falls back to scalar printing or YAML output. - [ ] Text without a template prints strings, nonempty string lists, numbers, and booleans directly; structured values, empty collections, and null use the shared YAML renderer. Cover explicit `--format text` for those values without introducing a separate pretty-printer. - [ ] The integration chooses concise/detailed content; changing format does not implicitly change the selected detail level. Core owns rendering and delivery in both templated and non-templated paths. - [ ] The invocation and writer-based public APIs share rendering behavior; handlers submit report data without their own format switches or encoder setup. Existing quiet-mode, presentation-failure, and domain-outcome behavior is preserved through the Reporter lifecycle. - [ ] Core-serialized ordinary Go reports follow the standard JSON contract, including JSON tags, supported custom serialization, and selected omissions. Conflicting YAML tags do not rename fields or change values in YAML output. Verify that automatic selection follows the resulting logical shape. - [ ] Representative reports retain null/false/zero/empty distinctions and numeric values through conversion, including large integers. Unsupported values and serialization failures remain observable presentation failures. - [ ] Safe inspection YAML is explicitly converted to ordinary Go report values in core and uses the shared renderers. Preserve types, presence/null/empty distinctions, numeric precision, sequence order, and redaction. Do not require mapping order or source formatting, or substitute runtime configuration structs. Conversion failures are observable; ordinary strings are not parsed as YAML. - [ ] A superseding ADR records the replacement of native-writer, mapping-order, and separate-document requirements in ADR 0007 and the combined-display ordering requirement in ADR 0009; canonical contracts are updated with implementation. - [ ] `config show --scope all` hands off one mapping keyed by scope identifier, including when only one scope is registered. All formats retain scope identity and safe values without injecting metadata into configuration fields. Cover configurations with fields named `scope` or `config`, single-scope unwrapped output, and failure before combined display. Do not assert aggregate scope order. - [ ] Core, both integrations, and a maintained application-owned command exercise the public reporting capability. Suitable duplicate selection and encoding code is removed; core has no optional integration dependencies. - [ ] Dependency, checksums, attribution commit links, and candidate notes match the final selected module versions. - [ ] All three compatibility changes and corrected credential wording are documented, with earlier v0.18.0 migration guidance retained where relevant. - [ ] The authentication response-limit reason survives report projection with native unknown facts. Smoke preparation errors retain supported causes and operational outcomes, including the no-report case; no model dispatch is introduced by CommandKit to handle them. - [ ] `promptkit show prepared PROMPT_ID` forwards the intended request and faithfully reports native fields, using automatic selection and accepting universal format choices. Help identifies the argument as a prompt ID and explains resource I/O and rendered content disclosure. Its CLI path makes no model call and does not create/execute retained prepared handles. - [ ] New flags preserve selected omission/empty/zero semantics, parse malformed inputs through the existing usage path, and do not leak state between runs. Numeric decoding of provider JSON and configuration overrides follows the same policy in OD-2 and OD-11, including nested values and input-error behavior. - [ ] The small, centralized internal CLI JSON conversion helper documents the numeric policy and its rationale in code comments. Cover integer boundaries, decimal/exponent forms, nested objects/arrays, and range errors. Accept ordinary floating-point approximation; do not add arbitrary-precision fallbacks or a public/general-purpose numeric conversion API. - [ ] The same public execution-flag collection works in a standard subcommand and an application-owned command with its own typed input. Parsing, presence, metadata, and selected subsets remain consistent; omitted retry values retain the applicable native defaults. Application execution behavior remains outside the collection. - [ ] Canonical `--llm-` flags and scoped convenience aliases follow OD-2. Alias generation covers only enabled commands and applicable flags, shares canonical binding/presence behavior, and preserves mixed-spelling occurrence order. Generic spellings remain available to unrelated application commands. - [ ] The convenient installation collection includes commands and their scoped aliases; canonical-only installation remains available. Help and migration guidance explain both forms without requiring consumer-maintained alias lists. - [ ] Text and file input names and aliases follow OD-2. Literal content, including empty text, reaches native inline inputs; file bindings remain file references. Examples, help, and documentation use the selected meanings. Verify that the last command-line occurrence for a name wins across text/file forms and all aliases, preserving actual occurrence order. - [ ] Output-contract override and appended-message flags remain outside this adoption, with their operator use cases retained in future work. - [ ] Opt-in namespace selectors combine declared suite defaults with supplied fields in one native view update. Omission preserves each declared default; explicit empty values clear only the selected default. Qualified selections and catalog filters retain their native meanings. Custom scoped loaders remain usable without the option. Canonical namespace names and scoped aliases match OD-3 and its agreed applicability table. Requirements inspection retains optional profile selection and profile namespace resolution; help explains that the profile establishes report identity, not discovered dependencies. Cover prompt-default fallback, missing profile selection, and explicitly selected short profile IDs without rewriting configured default references. - [ ] The full configuration suite retains six subcommands. Explanation discovery and validation diagnostics are modes of existing commands, with capability-aware help and selected mode/flag combination checks. - [ ] Bare `config explain` displays help successfully, presenting `--list` and `--path` as the two alternatives. Selecting both modes is a usage error; explicitly supplied `--path ""` selects root explanation rather than help. - [ ] Discovery supplies a compact text template, which core selects when no format is requested, with compact path/presence/explicitness fields and the selected `--historical`, `--under`, and `--explicit` behavior. Historical-only paths and unavailable discovery are not misreported as current implicit values or an empty configuration. - [ ] Metadata discovery through `config explain` distinguishes effective and historical paths, retains available history on absent lookup, and projects native field/change records. - [ ] Default `config diff` retains its concise additions/changes/deletions report. Optional `--details` uses the same comparison records to present both snapshots and presence/redaction/hidden-change evidence. Cover additions, deletions, explicit null, empty comparisons, sequence-level changes, and report-delivery failures without extra configuration loads or comparisons. Detailed YAML uses one before/after entry per path and an explicit empty list when there are no differences. - [ ] Focused display preserves native snapshot content and distinguishes missing/historical-only paths from explicit null. Whole-document display preserves safe inspection values through the shared renderers. Focused display uses one scope and hands off the logical value without a snapshot wrapper or text template; core applies automatic or explicit selection. Absent effective paths and unknown source IDs produce clear operational failures. - [ ] Source-ID selection works on successful and failed acquisitions. Path, explicitness, severity, and code filters preserve the selected evidence and source references without masking the acquisition outcome. - [ ] Comparison sides start independently from ordinary application defaults. Supplied config/overlay selections, domain selectors, and their presence apply only to their own side, including repeatable values. Cover left-only, right-only, both-side, neither-side, and partially supplied right selections; no omitted right field inherits from the left. Preserve side-specific checks and the shared-state lifecycle. Command-wide controls remain shared. - [ ] A superseding ADR records OD-9's replacement of ADR 0012's inheritance and shared-selector application rules. Update canonical CLI/API contracts and examples with implementation, including cases that now require repeating a common nondefault selection on both sides. - [ ] Assertion mode distinguishes equality, native differences (including hidden changes), usage errors, and operational failures with statuses `0`, `3`, `2`, and `1` respectively, without changing ordinary diff outcomes. Report-delivery failures remain observable. - [ ] Only supplied CLI overrides reach opted-in loaders under OD-11, with typed values and safe flag labels. `--set` applies only to the left comparison side, and `--against-set` only to the right; omission supplies no CLI override records for that side. Native errors and returned provenance are preserved. No tests independently re-establish ConfigKit override semantics. - [ ] Default validation remains concise; `--details` selects the additional diagnostic report with a text template. Core automatically selects text when that template is supplied, while explicit formats still win. Changing format alone does not enable detailed mode. Severity/code filters, evidence availability, no-match presentation, and known duplicate-warning handling preserve the underlying validation outcome. - [ ] `config sources` and `config validate --details` report available evidence with an acquisition error; the original failure, unavailable-versus-empty evidence, cancellation, and report-delivery failures remain distinguishable. - [ ] Existing providers remain usable; help, version, and capability discovery do not start acquisition. New operation/flag metadata and static completion match the implemented surface. - [ ] Maintained consumer examples demonstrate the selected CLI tasks and the configuration failure workflow with deterministic local evidence, including collection reuse by an application-owned command. - [ ] Suitable reports use direct Go-value serialization or thin projections, sharing the core representation and rendering machinery. Necessary adapters preserve native meaning without duplicating a full report tree per format. - [ ] Canonical documentation, module release notes, and roadmap links agree with the implemented boundary. Open decisions are resolved or deliberately superseded before the corresponding behavior is claimed complete. - [ ] Final independent-module and aligned-workspace suites pass, with the dependency identities used by each recorded. With the documented Go 1.27.0 toolchain selected, run `GOWORK=off GOTOOLCHAIN=local go test ./...` independently in the root, `integrations/ckconfig`, and `integrations/ckprompt`. Prepare dependencies before offline execution as described in the [release procedure](../release.md). Then validate the aligned workspace from the root with: ```sh GOTOOLCHAIN=local go test ./... GOTOOLCHAIN=local go test ./integrations/ckconfig/... GOTOOLCHAIN=local go test ./integrations/ckprompt/... ``` Use the [development guide](../development.md) for toolchain/workspace setup and documentation checks. Reuse successful checks for unchanged content; these adoption checks do not add permanent publication gates. The earlier disposable dependency-only compatibility test is preliminary evidence, not completion evidence for these features. ## Deferred work Focused backend inspection remains in [future work](future.md#promptkit-inspection-and-selection-extensions) until a released upstream API supports it. Do not reconstruct backend selection from configuration to deliver it in this roadmap. 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 These decisions concern significant choices within the proposed scope. Resolved items retain their numbers and record the agreed decision. OD numbers are local to this roadmap, not the retired adoption documents. The core ownership, JSON representation conventions, text printing/templates, universal-format, automatic-selection, and joint format-delivery decisions are now agreed above. Remaining details are listed under [remaining core reporting implementation details](#remaining-core-reporting-implementation-details). CLI JSON number decoding for both integrations, namespace applicability, and independent comparison defaults are agreed. Outstanding operator choices are whether to standardize explicit empty collections when application defaults are nonempty (OD-9), and unusual-path grammar and loader composition (OD-11). Inheritance-clearing flags are no longer needed. Exact helper signatures, typed binding composition, flag collision handling, and report layouts remain implementation choices, not unresolved scope. ### OD-1: Preview command and report presentation **Agreed:** use `promptkit show prepared PROMPT_ID` with the complete relevant `PreparedRun` projection. 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 definition 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 using existing core APIs. 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 conversion API, or extensible numeric framework is selected. CommandKit is a Go library for Go applications and deliberately accepts the precision and range of these Go types. It does not compensate for their limits with 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. Centralize the bounded CLI JSON conversion utility; its placement across the independent modules is an implementation task that must respect module ownership. 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. CommandKit is alpha with no consumers; redesign without compatibility constraints is explicitly accepted for these flags. Update implementation, examples, help, and documentation together; do not retain old meanings merely for compatibility. 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` no longer means a file path; 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. Select the necessary binding composition during implementation; do not claim this behavior from independent flag binding alone. **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, existing scoped loaders continue as before. 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 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.19.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; retaining it is a presentation choice, not a compatibility constraint. 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. Retain current aggregate stopping behavior; detailed output does not promise exhaustive validation across all scopes. Partial-evidence and cancellation presentation should use the same simple report values and existing reporting lifecycle, with exact layout refined during implementation and practical testing. ### OD-7: Module release and interim workspace coordination **Agreed:** complete the core reporting prerequisite and planned integration work together rather than splitting out a dependency-only PromptKit release. With no current consumers, an early compatibility release has no demonstrated benefit. Prepare the core release supplying the reporting API, 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 previous inheritance model, including existing config/overlay behavior and shared application selectors. When implementation lands, record the change in a superseding ADR for the affected decisions in ADR 0012, retaining its accepted decision text as history, and update current CLI/API contracts and examples. Exact helper signatures and flag collision handling remain implementation design tasks. **Remaining collection question:** omission already means the ordinary collection for that side, so no flag is needed to clear inherited left-side values. The earlier proposed `--against-clear-*` flags are not selected. Explicitly replacing an application's nonempty default collection with an empty collection is a separate, symmetric question for either side: decide whether it needs a standard capability or should remain with application-declared bindings. No empty-collection grammar is selected here, and an empty string element is not implicitly an empty collection. ### 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. The loader contract must state how it combines these records with any existing application-owned overrides; the generic adapter cannot inject them into an arbitrary loader after the load has completed. **Agreed numeric conversion:** adopt the ordinary Go numeric policy in OD-2 for both `--set` and `--against-set`, including nested objects and arrays. Integer syntax uses `int64`, with `uint64` for larger representable nonnegative values; decimal or exponent syntax uses `float64`. Accept ordinary floating-point approximation and report numeric range errors as input errors. Temporary `json.Number` values are converted before forwarding to ConfigKit. Use the same small, centralized internal CLI JSON utility and required policy comments; no arbitrary-precision fallback or public numeric conversion API is selected. **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. Prefer inline assignments for ordinary one-value experiments. This is the largest remaining loader integration design item; revisit scope explicitly if the required acquisition changes prove disproportionate rather than silently dropping the agreed feature. Settle these details before implementation: - Split at the first `=`; JSON supplies typed null, boolean, string, numeric, array, and object values, with the agreed numeric policy above. An unambiguous alternate input form may be needed for pointer keys containing `=`. - 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. - Follow the released mapping-path constraints, including root/index and schema-version restrictions, without extending them into 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. A structured override file is not selected as the primary interface: it handles complex values and unusual keys well but adds file setup to ordinary one-value experiments. It remains a possible supplemental form if needed to resolve the open grammar cases. 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.