Files
commandkit/docs/roadmap/promptkit.md

373 lines
21 KiB
Markdown

# Adopt PromptKit v0.14.0 and expose comparison and catalogs
Status: accepted feature end state; implementation has not started. Scope,
ownership, catalog API, and initial presentation choices are settled.
## Purpose and authority
CommandKit provides useful, consistent access to capabilities owned elsewhere.
Adopt PromptKit v0.14.0 and expose its native configuration comparison and
definition catalogs without requiring applications to duplicate command
infrastructure. Defer a standard command for `Engine.InspectRequirements` to
the next pass.
CommandKit owns command vocabulary, registration, selection, coordination,
presentation, and invocation outcomes. PromptKit owns the meaning of its
configuration inspection and catalogs, including which effective definitions
exist and the comparison capability it exposes. PromptKit delegates its native
comparison to ConfigKit. The adopted upstream public contracts remain
authoritative; this roadmap does not establish a second CommandKit definition
of their semantics or disclosure rules.
The [architecture policy](../policy/architecture.md) controls dependency direction
and ownership. [ADR 0004](../adr/0004-standard-inspection-surface.md) already
selects the standard catalog commands;
[ADR 0008](../adr/0008-semantic-configuration-diff.md) governs native comparison,
[ADR 0009](../adr/0009-configuration-scopes.md) governs independent scope
capabilities, and [ADR 0010](../adr/0010-optional-integration-modules.md) governs
optional modules. [ADR 0011](../adr/0011-captured-declarations-and-installation.md)
and [ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md) govern captured
declarations and input/state lifetimes. Existing deliberately selected contracts
control; prototype implementation shapes receive no compatibility preference.
This roadmap defines the selected end state. A later implementation plan should
sequence the work. The present pass updates only this roadmap.
## Current baseline
Baseline: CommandKit commit `ab270e2`.
CommandKit is a prerelease alpha codebase with no existing consumers. The
maintained consumer examples demonstrate intended usage; this adoption needs no
consumer migration plan.
| Owner | Current state |
| --- | --- |
| Core | Go 1.26.0; declarations, registration, typed bindings, dispatch, help/version, diagnostics, and outcomes. Cobra/pflag remain internal. No optional owning-library dependency. ReleaseKit v0.4.0 is the declared maintainer tool. |
| `integrations/ckconfig` | ConfigKit v0.7.1; independent validate/show/sources/explain/diff capabilities, paired selection/input preparation, and the shared YAML comparison report and delivery path. Report placement uses a report-local mapping index. |
| `integrations/ckprompt` | PromptKit v0.12.0 and ConfigKit v0.7.1. `ConfigScope` exposes validate/show/sources/explain, without comparison. `Suite` and `FromEngine` expose named prompt/profile inspection; `Command` generates only `promptkit show` children. |
| Maintained composed consumer | Demonstrates both configuration scopes, app configuration comparison, named prompt/profile inspection, and an application-owned session command. Application configuration caching distinguishes selections and supplied campaign inputs. |
| Deferred work | PromptKit comparison and catalogs are recorded as future capabilities in [deferred.md](deferred.md). They are targets of this adoption; requirement inspection is deferred separately. |
The existing [ckprompt contracts and adapters](../../integrations/ckprompt/adapters.go)
and [command assembly](../../integrations/ckprompt/command.go) are the starting
points. ckprompt already depends on ckconfig's public scope contracts; no new
module or dependency reversal is needed.
## Upstream adoption
Target PromptKit v0.14.0, source commit
`143c6e9b3a675872117b0471e2ff8bcb25055a54`. Relevant pinned sources are its
[v0.13.0 release notes](https://gitea.maximumdirect.net/eric/promptkit/src/commit/143c6e9b3a675872117b0471e2ff8bcb25055a54/docs/releases/v0.13.0.md),
[v0.14.0 release notes](https://gitea.maximumdirect.net/eric/promptkit/src/commit/143c6e9b3a675872117b0471e2ff8bcb25055a54/docs/releases/v0.14.0.md),
[configuration inspection API](https://gitea.maximumdirect.net/eric/promptkit/src/commit/143c6e9b3a675872117b0471e2ff8bcb25055a54/configuration_inspection.go),
and [listing API](https://gitea.maximumdirect.net/eric/promptkit/src/commit/143c6e9b3a675872117b0471e2ff8bcb25055a54/listing.go).
Relative to CommandKit's selected v0.12.0:
- v0.13.0 adds `Engine.ListPrompts`, `Engine.ListProfiles`, and
`Engine.InspectRequirements`, plus allocation and inspection improvements.
- v0.14.0 adds `ConfigurationInspection.Diff`, returning ConfigKit's public
difference records from two captured configuration inspections.
- The Go consumer minimum becomes 1.26.0, already met by all CommandKit modules.
ConfigKit v0.7.1 and the YAML version also match CommandKit's current selection.
- PromptKit selects ReleaseKit v0.4.1 as its maintainer tool. That version is
already selected through ConfigKit in the integration graphs. Adoption does
not itself change core's separately declared release tool or launcher.
The reviewed existing public inspection and construction signatures remain
available. Adoption must still check CommandKit's existing reports and error
handling against the upgraded implementation; a source review is not evidence
that the upgraded integration suites have passed. No upstream feature addition
is needed for the selected comparison and catalog goals.
## Target ownership and package shape
| Owner | Target responsibility |
| --- | --- |
| PromptKit | Supported configuration comparison and catalog APIs, effective membership, identity/version interpretation, native results, ownership, and disclosure contracts. |
| ConfigKit | Native effective-value comparison and paired safe snapshots used by PromptKit. |
| ckprompt | PromptKit adapters; engine acquisition and diagnostic adaptation; declaring comparison on its configuration scope; catalog callbacks, standard list handlers, and catalog presentation. |
| ckconfig | The existing `config` family, capability preflight, selection inheritance, paired typed inputs, shared-state coordination, comparison YAML rendering, and report delivery. |
| Core | Existing captured declarations, binding conversion/presence, installation, dispatch, help/version, and outcomes. No PromptKit-specific model. |
| Application | Source definitions, domain selector interpretation, loaders and caches, callback effects, runtime operations, stream selection, and process exit. |
Dependencies continue to point from ckprompt to ckconfig and core. ckconfig does
not import or require ckprompt or PromptKit; core remains independent of both
integrations. Reuse ckconfig's public contracts and installed command paths.
No duplicate comparison renderer, core provider registry, comparison facet,
backend change, sibling-internal import, or general plugin framework is needed.
Private helper organization remains an implementation choice.
## PromptKit configuration comparison
### Operator end state
`ckprompt.ConfigScope(loadEngine)` declares `ckconfig.Diff` alongside its existing
operations. Installing that scope through `ckconfig.Command` makes these
invocations available:
```text
app config diff --scope promptkit --config before.yml --against-config after.yml
app config diff --scope promptkit --config base.yml --against-overlay candidate
```
These are target invocations, not currently implemented PromptKit comparisons.
They use the existing [comparison CLI contract](../cli.md#compare-configuration-selections):
one scope, left selectors and inherited right overrides, shared applicable domain
selector values, YAML-only additions/changes/deletions presentation, and success
for completed comparisons regardless of whether differences exist. There is no
new `promptkit diff` command, scope aggregation, report envelope, or exit status.
Help and `config scopes` reflect the actual declared capability. Other scopes
remain free to support their own operation subsets.
### Adapter end state
The scope's `Compare` callback consumes the existing
`ckconfig.ComparisonRequest[I]` and shared `S`. ckconfig prepares and checks each
reached side's typed input, then initializes shared state once. The bundled
PromptKit adapter invokes the supplied engine loader for left and then right,
using each side's selection/input and that same state, obtains each engine's
`InspectConfiguration` view, and calls `left.Diff(right)`.
Return `commandkit.Acquired[[]configkit.Difference]` with accumulated diagnostics
and supported error identity preserved. The existing ckconfig report path
consumes those records. Ordinary operations continue through `Acquire` and the
existing inspection facets. A caller may narrow the scope's capabilities or
supply its own pair provider under the existing scope contract; original adapter
construction errors remain attached when capabilities are narrowed.
For the bundled adapter, retain diagnostics from each reached load or inspection,
identify left/right context and native source legends, keep left diagnostics if
right acquisition fails, and keep both sides' diagnostics if comparison fails.
Use existing cancellation checks at operation boundaries and finish report
preparation before delivery. The upstream Diff method is synchronous and takes
no context; do not promise interruption inside it or transactional writer output.
Equal selections alone do not skip the pair provider or the bundled adapter's
reached loader calls. Application caches determine whether calls construct new
engines or reuse captured ones. CommandKit does not supply, inspect, or repair
those caches or promise physical source reloads or distinct factory objects.
### Meaning and presentation
Delegate to PromptKit's adopted comparison contract. Its current API compares
captured effective configurations through ConfigKit, rather than source-history
text, referenced file contents, resolved credentials, or later request-specific
execution state. These are upstream semantics, not independently frozen
CommandKit guarantees. An empty configuration comparison does not establish
equivalent execution.
Preserve native record evidence at the provider boundary and use the existing
safe right-side YAML presentation. Follow the adopted upstream classification;
do not add blanket masking of provider parameters or infer metadata from mask
text. Ordinary prompt/provider content can remain application data. Applications
retain their disclosure choices and callback effects.
## Prompt and profile catalogs
### Operator end state
Extend the optional `promptkit` family with the command paths already selected
by ADR 0004:
```text
app promptkit list prompts
app promptkit list profiles
```
Each command accepts configuration/overlay selection and the applicable existing
suite domain selectors, without requiring a definition ID or exact-version
operand. These commands use the namespace's engine selection, rather than a
new configuration-scope selector. Catalogs use the initial YAML presentation
defined below. No filtering, pagination, version-priority rule, requirement
discovery, or per-definition readiness check is added in this delivery.
The bundled adapter obtains prompt ID/version pairs with `Engine.ListPrompts`
and profile IDs with `Engine.ListProfiles`. It preserves returned identities
and order without reconstructing catalogs from configuration YAML or invoking
named inspection for each entry. PromptKit's current lists describe effective
membership, include maintained definitions that remain effective, and order
identities lexically; prompt versions are not ranked semantically. Upstream
remains authoritative if its adopted contract evolves.
Successful empty catalogs render as `[]`. Both nil and allocated empty slices
returned by a successful provider represent an empty inventory. Membership does
not prove execution readiness. Identifiers retain their exact values, including values
that require YAML quoting; CommandKit does not normalize identifiers or promise
that catalog data is safe for arbitrary public disclosure.
### Consumer and invocation end state
Add independently optional catalog providers to `ckprompt.Suite[I, S]` with these
signatures:
```go
ListPrompts func(context.Context, ckconfig.Selection, I, S) (commandkit.Acquired[[]promptkit.PromptIdentity], error)
ListProfiles func(context.Context, ckconfig.Selection, I, S) (commandkit.Acquired[[]string], error)
```
Catalog commands have no selected definition ID or version. Their standard
selection data fits `ckconfig.Selection`; domain values belong in `I`. Direct
selection input matches the engine loader and existing `Suite.CheckInput`
contract. A separate catalog request wrapper would add no information today.
Results reuse meaningful upstream public types.
`FromEngine(loadEngine)` supplies both catalog callbacks alongside the existing
named-inspection callbacks. It acquires an engine only when the selected catalog
operation is reached, calls the corresponding native listing API, and returns
adapted load diagnostics with the result or error. Listing itself does not
execute prompts or contact model providers; application loaders and custom
callbacks retain their own effects.
`Command(suite)` captures metadata, bindings, and callback references and emits
only supplied operations. Listing can be installed without either named-show
callback; named-show operations can remain installed without catalog callbacks.
Emit each intermediate group only when it has supplied operations: a catalog-only
suite has no `show` group, and a show-only suite has no `list` group, including in
help output.
An entirely absent suite contributes no namespace or commands, while attached
construction errors are still reported. A nonempty family remains root-only and
owns its namespace under the existing installation contract. Importing ckprompt
does not install a family; configuration-scope and definition-family installation
remain independent.
For one reached catalog invocation, prepare one `I`, apply the captured converted
selectors, complete existing input checks, initialize `S` once, and invoke the
selected provider. Preserve supplied empty/false/zero values, original binding
identity, nil-factory zero values, and caller ownership. Installation, help, and
version invoke neither suite factories nor providers; operator-requested listing
does acquire its selected inventory. Use existing usage/operational outcomes,
diagnostic delivery, cancellation boundaries, and write-failure handling.
### Selecting capabilities
The bundled adapters supply all supported operations: `FromEngine` supplies both
catalogs and both named inspections, and `ConfigScope` includes comparison.
Applications can narrow these declarations before passing them to `Command`.
For example, given an application engine loader `loadEngine`, a show-only
definition suite and a configuration scope limited to show and validate are:
```go
definitions := ckprompt.FromEngine(loadEngine)
definitions.ListPrompts = nil
definitions.ListProfiles = nil
scope := ckprompt.ConfigScope(loadEngine)
scope.Operations = []ckconfig.Operation{ckconfig.Show, ckconfig.Validate}
```
### Initial catalog presentation
Deliver YAML only, default to YAML, and accept explicit `--format yaml`. Catalog
sequences are readable for operators and directly usable by automation. YAML
preserves arbitrary identity strings without a separate text escaping convention.
These are initial catalog presentation choices; additional formats can follow
operator needs. Existing named-show formats remain available.
Emit one bare sequence per invocation. Prompt entries have explicit `id` and
`version` string fields; profile entries are strings. For example:
```yaml
- id: briefing
version: "1"
- id: briefing
version: "2"
```
```yaml
- autumn
- spring
```
The command path identifies the resource, so a bare collection is simple to
consume without an envelope for unused metadata. Preserve provider order and
exact strings; quote through the YAML encoder rather than interpreting
numeric-looking versions. CommandKit defines these report fields explicitly;
serialization of an upstream Go struct does not define the CLI schema.
## Work needed from the baseline
### Dependencies and distribution
- Upgrade ckprompt's PromptKit requirement from v0.12.0 to v0.14.0 and reconcile
real module-local checksums and legitimate indirect requirements. Retain
ConfigKit v0.7.1, Go 1.26.0, and the existing core/ckconfig versioning policy.
- Preserve ignored development workspace wiring. Distributed manifests must not
acquire sibling replacements or invented checksums for unpublished CommandKit
modules. Reuse the existing isolated-module validation approach where needed.
- Update PromptKit's module-local attribution and source-pinned license/notice
links under the [OSS policy](../policy/oss.md). Review actual selected graphs;
do not copy workspace-selected tool versions into core's declaration/notices.
- Reconcile prepared integration release notes with the delivered capabilities
under the [release policy](../policy/release.md). Publication, tag selection,
and independent module release ordering remain with the
[release procedure](../release.md); this adoption does not publish a release.
### Adapters and command assembly
- Extend `ConfigScope` with the native PromptKit comparison provider, retaining
ordinary acquisition and appropriate side diagnostics. Route results through
the existing ckconfig comparison implementation.
- Adapt diagnostic acquisition for comparison deliberately. The current
`loadPromptKitEngine` helper uses a single `promptkit` scope label and can
return on cancellation before collecting inspection diagnostics. Account for
side labels, source legends, and retained diagnostics at failure and
cancellation boundaries when reusing or adjusting it.
- Extend `Suite`, `FromEngine`, and family assembly for independent prompt/profile
catalog providers. Use core declarations and typed binding composition for
selection and input preparation; add no second parser.
- Implement the selected catalog YAML presentation, including `[]` for both nil
and allocated empty successful results.
- Keep implementation proportionate. Reuse existing acquisition, preparation,
diagnostic, YAML, and outcome helpers where they fit; introduce only the
concrete helper changes needed for the new operations.
### Examples, documentation, and behavioral evidence
- Extend the maintained composed consumer with PromptKit-scope comparison and
both catalog commands. Reuse its selection-aware application loading so two
configurations yield meaningfully different engine inspections. Its cache
choices remain example choices, not policy for consumers.
- When behavior lands, update owning GoDoc, the CLI reference, consumer guidance,
module README, and internal overview. Document the bundled adapters' complete
operation sets and how to narrow them. Replace claims that PromptKit comparison
and catalogs are unavailable. Reconcile the completed ConfigKit roadmap's
PromptKit status and the deferred-work record; retain requirement inspection
as explicitly deferred without inventing its future syntax.
- Validate existing show/validate/sources/explain behavior, named prompt/profile
reports, app comparison, and the composed domain command against the upgraded
dependency. Add focused evidence for catalog-only and mixed capabilities,
callback-free help with absent intermediate groups omitted, input/state timing,
exact identities and versions, nil and allocated empty inventories, native
comparison, diagnostics retained across side failures, cancellation, and report
delivery failures.
- Prefer assembled behavior and real fast native collaborators. Reuse ckconfig's
existing report/lifecycle coverage; do not duplicate ConfigKit's comparator or
PromptKit's full catalog suite, freeze private layout or polling counts, or
introduce performance, concurrency, or release gates through tests.
- Establish compatibility through relevant module suites, maintained consumers,
and workspace-off dependency/import checks. Local replacements for unpublished
CommandKit prerequisites prove local-source compatibility, not availability of
future tags. These checks belong to implementation, not this prose-only pass.
## Scope limits and completion
The target is PromptKit v0.14.0 adoption, usable PromptKit-scope configuration
comparison, and independently selectable prompt/profile catalog commands with
current API/CLI documentation and representative consumer evidence. Existing
ADRs cover this direction; exact catalog signatures and report shapes belong in
their canonical owners when implemented.
`Engine.InspectRequirements` is available through the upgraded dependency, but a
standard CLI command for it is deferred to the next pass. It is not integrated
into configuration validation or ordinary prompt display here. Execution,
preparation, rendering, credential probing, mutation, independent per-side domain
selectors, assertion statuses, JSON output, new scope aggregation, and backend
changes remain outside this delivery.
Completion requires all selected capabilities and relevant dependency metadata,
notices, docs, examples, and boundary validation. The decisions needed for an
implementation plan are settled.