diff --git a/docs/development.md b/docs/development.md index d1ad7b1..0232bcc 100644 --- a/docs/development.md +++ b/docs/development.md @@ -52,7 +52,7 @@ canonical documentation owners. | Public facade or adapter boundaries | [Internal overview](internal/overview.md), [ADR 0003](adr/0003-public-facade.md) as scoped by [ADR 0010](adr/0010-optional-integration-modules.md), and the architecture policy | | Module ownership and public contracts | [Consumer guide](consumers/guide.md), [internal overview](internal/overview.md), [core GoDoc](../doc.go), [ckconfig GoDoc](../integrations/ckconfig/doc.go), [ckprompt GoDoc](../integrations/ckprompt/doc.go), and applicable ADRs | | Deferred capabilities and proposals | [Deferred work](roadmap/deferred.md) | -| Completed planning and implementation history | [Earlier retired records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap) and [completed module implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/bb2528532b78d30e52f5082e491a5e1fd9b0fb99/docs/roadmap) in Git history | +| Completed planning and implementation history | [Completed ConfigKit and PromptKit adoption and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/8a82620dfcd34c0ae56bbecb0d014eb49786bc92/docs/roadmap), [earlier retired records](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/6bc37e7ba64ca0920b4d0cc77039a18d4006b24e/docs/roadmap), and [completed module implementation and remediation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/bb2528532b78d30e52f5082e491a5e1fd9b0fb99/docs/roadmap) in Git history | | Release tooling | [Maintainer release procedure](release.md) | | Performance maintenance | [Internal overview](internal/overview.md), existing benchmarks, and [deferred efficiency work](roadmap/deferred.md#possible-further-efficiency-work) | | Licensing or incorporated material | [Project grant](../COPYRIGHT), [license texts](../LICENSE), and [attribution](oss/attribution.md) | @@ -104,7 +104,7 @@ go test ./... The workspace checks package behavior. Workspace-off checks with each module's own dependency graph are separate evidence. For unpublished CommandKit dependency -versions, the [completed sprint's validation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/bb2528532b78d30e52f5082e491a5e1fd9b0fb99/docs/roadmap/implementation.md#stage-16-validate-the-complete-end-state-and-finish-the-sprint) +versions, the [completed integration validation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/8a82620dfcd34c0ae56bbecb0d014eb49786bc92/docs/roadmap/implementation.md#stage-12-validate-the-complete-end-state-and-finish) describes the disposable module-file procedure used during implementation. Format changed Go files with `gofmt`. The [maintainer release procedure](release.md) owns candidate preparation and diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md deleted file mode 100644 index daa693c..0000000 --- a/docs/roadmap/configkit.md +++ /dev/null @@ -1,391 +0,0 @@ -# Adopt ConfigKit v0.7.1 and expose native configuration comparison - -Status: complete. ConfigKit v0.7.1 adoption and ConfigKit-backed `config diff`, -including distribution reconciliation and final validation, are implemented. -The [implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md) records completion evidence; -release publication remains a separate process. - -## Purpose and authority - -Adopt ConfigKit's current loading and inspection improvements and expose its -native effective-configuration comparison through CommandKit. Operators should -be able to compare two selections of one configuration scope, including the -effect of a selected overlay, without applications writing duplicate CLI or -comparison infrastructure. - -The revised [ADR 0008](../adr/0008-semantic-configuration-diff.md) owns native -comparison and paired safe disclosure. [ADR 0009](../adr/0009-configuration-scopes.md) -owns scope selection and independent capabilities; [ADR 0011](../adr/0011-captured-declarations-and-installation.md) -owns captured declarations, typed input, and shared state, refined for comparison -pairs by [ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). The -[architecture policy](../policy/architecture.md) controls ownership and dependency -direction. The accepted ADRs govern this roadmap's comparison direction. - -The repository is being developed as a pre-release alpha. Choose the simplest -coherent final API without preserving prototype shapes through compatibility -wrappers. Existing deliberately selected contracts still control; changes to -published releases follow the [release policy](../policy/release.md). - -This work consumes ConfigKit's supported public API. No upstream extension is -required for the selected comparison goal. ConfigKit owns comparison and safe -disclosure; CommandKit owns selection, coordination, adaptation, and presentation. - -## Current baseline - -| Owner | Current state | -| --- | --- | -| Core module | Go 1.26.0; captured commands, typed bindings, dispatch, outcomes, help, and version. No ConfigKit dependency. ReleaseKit v0.4.0 is the declared maintainer tool. | -| `integrations/ckconfig` | Requires ConfigKit v0.7.1. `Scope`, `Suite`, `FromConfigKit`, and `AppCommand` expose independently declared validate/show/sources/explain/diff capabilities. | -| `integrations/ckprompt` | The later PromptKit adoption selects PromptKit v0.14.0 and ConfigKit v0.7.1. It adapts engine configuration and exposes native comparison, prompt/profile catalogs, and named definitions through ckconfig and core contracts. | -| Comparison status | ConfigKit-backed `config diff` and PromptKit engine-scope comparison are implemented. The [CLI reference](../cli.md#compare-configuration-selections) and [PromptKit adoption record](promptkit.md) describe current behavior; the [implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md) records ConfigKit completion. | - -The ConfigKit adapter acquires typed `*configkit.Result[T]` values and exposes -effective, source, and explanation facets through `View` for ordinary operations. -Its separate comparison callback retains `T`, loads both prepared selections, -and returns the native records from `configkit.Diff` without routing through -`View`. - -ConfigKit v0.7.1 identifies source commit -`6fffde4af8f31f99d3ee295c426eb3234cb0fb77`. Relative to the selected v0.5.0: - -- v0.6.0 reduces repeated loading, resolution, metadata, and inspection work. - Its Go 1.26.0 minimum is already met by CommandKit. -- v0.7.0 adds native frozen effective-value comparison. -- v0.7.1 changes the upstream maintainer tool to ReleaseKit v0.4.1, with no - runtime/API change from v0.7.0. - -The YAML dependency remains `go.yaml.in/yaml/v4 v4.0.0-rc.6`. Existing public -loading and inspection signatures are unchanged, and the integration suites pass -with the adopted dependency. See the pinned -[release notes](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/6fffde4af8f31f99d3ee295c426eb3234cb0fb77/docs/releases/v0.7.1.md) -and [comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/6fffde4af8f31f99d3ee295c426eb3234cb0fb77/docs/config.md#effective-configuration-diffs). - -## Dependency adoption and ownership - -Both integration modules select ConfigKit v0.7.1 and carry normal dependency -metadata for their actual graphs. Consumer Go minimums remain 1.26.0, and the -selected release toolchain remains 1.26.8. At completion of this ConfigKit work, -ckprompt still selected PromptKit v0.12.0; the later PromptKit adoption is tracked -in [promptkit.md](promptkit.md). -Core continues to have no ConfigKit or optional-integration dependency. - -ConfigKit's declared tool requirement brings ReleaseKit v0.4.1 into the integration -module graphs. Reconcile that selection through normal Go module resolution and -accurate attribution. A combined development workspace can also select that -version. This does not by itself change the core module's separately declared -release tool or authorize release-launcher changes; assess core through its own -workspace-off graph. - -Independent module versions remain independent of upstream ConfigKit's version. -Release preparation uses appropriate unused versions under the existing policy, -without moving tags or claiming unpublished dependencies are available. - -### Responsibility boundaries - -| Owner | Target responsibility | -| --- | --- | -| ConfigKit | Frozen effective-value equality, changed-region selection/order, sensitivity union, paired safe snapshots, hidden-change detection, and load semantics. | -| ckconfig | Comparison capability and provider contracts; typed ConfigKit adapter; `config diff` input preparation, acquisition coordination, reports, and upstream diagnostic adaptation. | -| Core | Existing declaration installation, flag conversion/presence, help, dispatch, cancellation context, and outcome/delivery mechanics. No comparison model or engine. | -| ckprompt | Continue existing integration behavior with the upgraded shared dependency and ckconfig API. Do not claim native PromptKit comparison support through this upgrade. | -| Consuming application | Configuration definitions, acquisition callback internals, loader/cache choices, domain interpretation, startup, and process exit. | - -## Operator behavior - -### Availability and scope selection - -The `config` family exposes `diff` when at least one scope declares the capability. -Help and `config scopes` report actual availability. A scope can support comparison -independently of other operations; enabling comparison elsewhere does not require -every scope to support it. Unsupported selections fail as usage errors before -acquisition. - -`config diff` selects one scope, defaults to `app`, and does not accept -`--scope all`, as selected by ADR 0009. It compares earlier/left and later/right -effective configurations. Both file comparison and base-versus-overlay comparison -use the providers' ordinary application-loading contracts. - -### Left and right selections - -Use existing `--config` and `--overlay` for the left side and add -`--against-config` and `--against-overlay` overrides for the right side. -Omitted right fields inherit the left field, including its supplied state; -explicit right values, including an empty string, replace it. Use the scope's -applicable typed domain selectors on both sides. This supports two files and -base-versus-overlay comparison while reusing familiar syntax and preserving -provider-owned defaults. Allow equal selections; they can produce a legitimate -empty diff without an invented requirement that an override be supplied. Do not -short-circuit acquisition merely because the selections are equal: caller-owned -loading may produce different effective results. - -For example, these are current invocations: - -```text -app config diff --config before.yml --against-config after.yml -app config diff --config base.yml --against-overlay candidate -app config diff --config base.yml --overlay current --against-overlay "" -``` - -Right-side inheritance is field-by-field. Overriding only the configuration still -inherits the left overlay. For either selection field: - -| Left field | Right override | Effective right field | -| --- | --- | --- | -| Omitted | Omitted | Omitted, preserving provider defaults | -| Supplied value | Omitted | Same value and supplied state as left | -| Explicit empty string | Omitted | Explicit empty string, still supplied | -| Any value/state | Supplied value | Right value, supplied | -| Any value/state | Explicit empty string | Empty string, supplied | - -The provider continues to interpret an explicitly empty overlay through its -ordinary loading contract; CommandKit does not define empty as disabling overlays. -Domain selector values are shared between sides in this delivery; independent -per-side domain selectors can be considered for a concrete consumer need. - -### Comparison meaning and disclosure - -Retain ConfigKit's native changed-region records at the provider boundary, including -semantic paths, left/right `Present` and `Redacted` states, safe YAML values, and -`HiddenChanged`. The YAML report deliberately presents a reduced view rather than -exposing all native metadata. The native contract owns detailed comparison -semantics; the important operator consequences are: - -- Changes reflect frozen effective load values, including defaults and recorded - domain resolution. Provenance or source-layout differences alone are not - effective changes. -- Compare final values, not source presence alone. Omitted and explicit-null - inputs may resolve equally for a typed field; an absent map key and a present - null-valued key can remain distinct in the final configuration. Nil and empty - containers also remain distinct. Mappings compare recursively; sequences report - atomic changed regions. -- Both sides receive the union of sensitivity from both loads. Structural - replacements can mask an entire region. -- A difference can exist even when its safe left/right YAML is identical. - `HiddenChanged` reports an actual concealed change; redaction alone does not. -- An empty successful diff supports equality within ConfigKit's inspected value - model. Typed secret references compare by configured name; credential rotation - behind an unchanged reference is outside that comparison. - -Reports use safe changed regions without inventing a coverage-gap inventory, -decoding redaction-marker text as metadata, identifying concealed members beyond -upstream disclosure, or adding separately rendered full configurations as if they -had received paired protection. Full paired document context and a sensitivity -audit are separate potential capabilities, not prerequisites here. - -### YAML report - -`config diff` emits one YAML document through the existing output streams. YAML -is the only report format for this delivery; explicit `--format yaml` is accepted. -Always include the three keys `additions`, `changes`, and `deletions` in that order. -Additions and changes preserve configuration hierarchy and contain only safe -right-side values; deletions are canonical JSON Pointer paths. For example: - -```yaml -additions: - server: - health_check: true -changes: - server: - port: 9090 - logging: - destination: null -deletions: - - /server/legacy_timeout -``` - -Classify each native difference by its presence fields: absent-left/present-right -is an addition, present-left/absent-right is a deletion, and present on both sides -is a change. Explicit null remains a value; do not encode deletion as null. -Changed sequences remain whole sequences, and native structural replacements -remain whole reported regions. Do not derive a second set of changes by comparing -rendered values or expanding atomic regions. - -Assemble additions and changes from ConfigKit's paired-safe right snapshots, -preserving YAML value types and semantic path components. Parsing and assembly -serve presentation only. Do not read unredacted configuration values or append -independently rendered full configurations. The result is a partial inspection -view, not a complete configuration or an automatically applicable patch. - -Omit separate `Redacted` and `HiddenChanged` metadata from this default view. -Every reported region changed, but a masked value within it need not have changed: -a public field in an atomic sequence may change while a secret remains unchanged. -A concealed-only change still appears in its native reported region even if the -safe snapshots are identical. Preserve native masks without interpreting marker -text; a literal public string resembling `[REDACTED]` remains an ordinary value. -The default report intentionally does not expose every distinction available in -the native records. A detailed metadata format can be considered separately if -needed; it is not required for this delivery. - -When a nonempty root mapping becomes an empty mapping, report the native -removed-key paths under `deletions`. The reduced report -need not add special metadata or a separate envelope solely to distinguish -exceptional whole-root empty/null transitions from an empty comparison. That -ambiguity is an accepted limit of this reduced report. Native comparison records -retain their distinctions; ordinary field-level null values and deletions retain -the selected reporting rules. - -Empty additions and changes render as `{}`; empty deletions render as `[]`. An -empty comparison therefore produces: - -```yaml -additions: {} -changes: {} -deletions: [] -``` - -This stable shape supports automated consumption without missing-key handling -and retains the accepted tolerance for exceptional whole-root ambiguity. Other -commands keep their existing formats. - -### Diagnostics and outcomes - -Successful comparisons return success whether they find differences, concealed -changes, or none. No assertion status or separate exit code is added. Load and -comparison failures retain operational classification and supported error -identity; selection/input errors retain usage classification. Output failures -use existing delivery and incomplete-report semantics. - -The ConfigKit adapter retains diagnostics from the acquired results, including -warnings and any load failure encountered. Present them through existing core -diagnostic delivery; preserve meaningful left/right context when needed to -identify the failing selection without losing wrapped error identity. Retain -left-side warnings if the right load fails, and diagnostics from both successful -loads if native comparison fails. Finish acquisition and native comparison before -writing a successful diff report. Cancellation is checked at ordinary operation -boundaries; do not promise interruption inside a synchronous upstream call. - -## Consumer API and execution lifecycle - -### Comparison provider and ConfigKit adapters - -`ckconfig.Scope[I, S]` exposes a narrow optional comparison callback. Its request -groups each side's selection with its separately prepared typed input and supplies -one shared state value separately. Return -`commandkit.Acquired[[]configkit.Difference]` plus an error, following the existing -acquisition convention. It reuses upstream public record types rather than -duplicating them solely to rename fields. The current API shape is: - -```go -type ComparisonSide[I any] struct { - Selection Selection - Input I -} - -type ComparisonRequest[I any] struct { - Left ComparisonSide[I] - Right ComparisonSide[I] -} - -// Current field on Scope[I, S]: -// Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error) -``` - -These are the implemented exports in `integrations/ckconfig/contracts.go`. -ADR 0012 records paired provider ownership and input/state lifetimes; GoDoc owns -the exact public declarations. - -`AppCommand` and `FromConfigKit` provide native comparison alongside their existing -supported operations, with ordinary capability narrowing available. They use the -same supplied typed loader for ordinary inspection and both comparison sides, -retaining `T` inside the adapter and passing successful results to `configkit.Diff`. -Do not compare rendered YAML or mutable `Result.Config`. - -Existing single-view acquisition remains responsible for ordinary operations. -A comparison-only scope can supply the pair callback without an unrelated -`Acquire` callback. Declared capabilities determine which callbacks must be wired. - -### Input preparation and acquisition lifecycle - -Use original typed binding identities and converted values, preserving explicit -empty, false, and zero selections. Convert supplied values through core once, -including help paths; applying values to both inputs does not parse them twice. - -For a reached comparison, initialize each selection's `I` separately, apply the -same applicable captured selector values, and check it with that side's -`Selection`. Finish both input checks before initializing `S` once and invoking -the pair provider. Omitted factories still supply zero values, including nil -pointers; separate calls do not guarantee distinct caller objects. Later factories -or loads need not run after failure. Declaration construction, installation, help, -version, and scope discovery leave input/state factories and acquisition/comparison -callbacks uninvoked. -ADR 0012 records this two-selection specialization of ADR 0011's suite lifecycle, -and the architecture policy reflects it. The exact API contract is in the Go -declarations and GoDoc. - -### Application-owned state and caches - -Generic result handling stays inside the owning adapter, without reflection, -private-core access, or result type assertions. Shared state supports consumer -caches whose keys distinguish the effective selections and any typed-input values -that affect loading. A cache that stores only one configuration can incorrectly -reuse the left result for the right and report equality. The composed example -demonstrates selection- and input-aware keys; CommandKit neither supplies nor -repairs application caches. Cache policy and factory objects remain caller-owned. - -## Design tradeoffs - -The chosen selection flags reuse existing configuration vocabulary and reduce -repetition for base-versus-overlay comparison. Symmetric `--left-config` / -`--right-config` and `--left-overlay` / `--right-overlay` flags would make each side -independent but add vocabulary and repetition. Independent per-side domain -selectors remain possible future work for a concrete consumer need. - -A comparison-capable facet on each ordinary `View` could share acquisition across -operations, but would require a compatibility contract between heterogeneous -facets and additional handle or type-assertion machinery. The typed pair provider -keeps both results inside their owning adapter and avoids that extra framework. - -A full difference envelope could expose both snapshots and all native metadata, -using YAML strings or parsed values. It would be more verbose than the selected -operator view. The three-category report retains configuration-shaped right-side -values while representing removals explicitly. Omitting empty categories would -shorten output but require missing-key handling; a separate text renderer adds no -needed operator value for this delivery. - -## Implementation record - -Dependency adoption, capability and typed-pair preparation, native adaptation, -YAML reporting, end-to-end execution, and both maintained comparison examples -are implemented. Current API and operator contracts belong to GoDoc, the -[CLI reference](../cli.md#compare-configuration-selections), the -[consumer guide](../consumers/guide.md#configkit-scopes), and the example -READMEs. The [implementation record](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md) records stage-by-stage -changes and completed validation, including -[distribution reconciliation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md#stage-12-reconcile-manifests-notices-and-pending-integration-release-notes) -and [final sprint validation](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md#stage-13-validate-the-complete-sprint-and-finish). -The isolated integration checks used local replacements for unpublished -CommandKit dependencies. They establish compatibility with local CommandKit -sources and released external dependencies, not availability of the intended -CommandKit module tags. No release was published as part of the sprint; -publication follows the [release procedure](../release.md). - -### Focused behavioral evidence - -Focused comparison coverage should protect the CommandKit boundary: capability -availability before callbacks, side selection/presence, chosen input/state -lifetime, native public and concealed changes, absent versus null values, and -empty successful comparisons. Include representative load/comparison errors, -diagnostics, cancellation, and output failure. Specifically cover left-side -warnings followed by a right-side load failure, and diagnostics from both loads -followed by a comparison failure. Verify that selection-aware caching does not -return the left result for the right selection. Include the three report -categories, explicit null versus deletion, concealed-only changes, and an -unchanged masked value inside a changed sequence. Existing inspection and composed -PromptKit behavior must continue to work. Reuse native collaborators and test -CommandKit's adaptation/reporting; do not duplicate ConfigKit's entire comparator -suite or impose performance thresholds. - -## Scope limits and completion - -This work delivers ConfigKit adoption and ConfigKit-backed `config diff`. -PromptKit upgrade/comparison/catalogs, JSON reports, per-element sequence matching, -resolved credential comparison, full paired document context, assertion mode, -provider caching, and core backend changes are outside this target. - -Completion means upgraded integration dependencies, usable native comparison -through declared scopes and convenience wiring, selected public API/CLI/report -contracts in their current owners, relevant maintained examples, accurate notices, -and sufficient boundary validation. No significant open decisions remain. -Implementation must not silently add contracts beyond this selected scope. -Publication follows the existing release procedure and is not performed by this -planning pass. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md deleted file mode 100644 index 4a96196..0000000 --- a/docs/roadmap/implementation.md +++ /dev/null @@ -1,763 +0,0 @@ -# Implement PromptKit comparison and catalogs - -Status: Stages 1–12 complete. - -## Scope and authority - -This plan implements the accepted [PromptKit feature roadmap](promptkit.md). -That roadmap owns the target state and product choices; this document assigns -work needed to reach it. Baseline: CommandKit commit `20e19b9`. ConfigKit -comparison is complete, ckprompt uses PromptKit v0.12.0, and PromptKit comparison -and catalogs are not yet exposed. - -Read [development orientation](../development.md) and applicable policies, -including [agent discipline](../policy/agents.md), -[architecture](../policy/architecture.md), [testing](../policy/testing.md), -[documentation ownership](../policy/documentation.md), [OSS](../policy/oss.md), -and [release policy](../policy/release.md). The accepted ADRs linked from the -feature roadmap govern declaration capture, scope capabilities, and paired inputs. - -CommandKit exposes capabilities owned by PromptKit and ConfigKit. It owns CLI -access and presentation, not a replacement definition of comparison or catalog -membership. Dependencies remain ckprompt to ckconfig and core. This sprint needs -no core API, backend, general registry, or additional module. - -The repository is an unreleased alpha with no downstream consumers. Give the -prototype shape no compatibility preference: choose straightforward private -helpers and refactor existing ones where useful. Preserve deliberately selected -contracts, not incidental implementation details. No compatibility wrappers, -migration period, or buildable intermediate commits are required. The final -assembled end state must build and pass relevant validation. - -### Execute the stages - -- Follow stages in order. Each stage is one bounded Luna assignment; inspect its - linked owners and current code before editing. -- Scope changes to that stage and necessary integration repairs. Reuse existing - paths rather than copying parser, comparison, or delivery infrastructure. -- Format changed Go files and add focused behavioral evidence as assigned. - Validation instructions apply during implementation, not this planning pass. - Use existing fast native fixtures; no model-provider access is needed. -- Add completion evidence under each completed stage: changes, checks actually - run, results, and validation deferred until a later stage. Do not mark the - adoption complete before its assembled behavior works. -- Commit completed nonempty units with plain English messages under the agent - policy. Do not create empty commits, publish releases, or push changes. -- Existing tests asserting that PromptKit comparison is unavailable become - obsolete intentionally. Replace them in their assigned stage; do not add - temporary behavior to preserve that expectation. - -| Target | Primary stages | -| --- | --- | -| PromptKit v0.14.0 and real dependency metadata | 1, 11, 12 | -| Side diagnostics and native configuration comparison | 2–4 | -| Optional native catalog providers | 5 | -| Catalog YAML presentation and command invocation | 6–8 | -| Maintained consumer and canonical documentation | 9–10 | -| Notices, prepared notes, and complete validation | 11–12 | - -## Stage 1: Adopt PromptKit and prepare module validation - -**Outcome:** ckprompt selects PromptKit v0.14.0 using real upstream metadata, -and the sprint has a usable local validation setup. - -**Steps** - -1. Upgrade `integrations/ckprompt/go.mod` from PromptKit v0.12.0 to v0.14.0, - pinned by the feature roadmap to upstream commit - `143c6e9b3a675872117b0471e2ff8bcb25055a54`. Reconcile legitimate indirect - requirements and real checksums using Go tooling against the released module. -2. Retain Go 1.26.0, ConfigKit v0.7.1, and existing independent CommandKit - prerequisites: core v0.2.0 and ckconfig v0.1.0. Core's declared ReleaseKit - v0.4.0 tool/launcher stays unchanged; integration graphs may select v0.4.1 - through upstream dependencies. -3. Preserve an existing ignored `go.work`; ensure it includes core, ckconfig, - and ckprompt. Commit neither workspace files nor sibling replacements. -4. Establish workspace-off checks using disposable copies of each integration's - module file and accompanying sum file in a temporary directory (`go.mod` and - `go.sum`, so `-modfile` finds the matching sums). Replace only unpublished - CommandKit prerequisites: core for ckconfig, and core plus ckconfig for ckprompt. - Resolve PromptKit and ConfigKit at real released versions. Keep disposable - files outside the tracked distribution. -5. If tidying a disposable module file, transfer legitimate requirements and sums - back without temporary replacements. Invent no sums for unpublished modules; - workspace selection is not evidence of an independently declared graph. - -**Validation and handoff** - -Run the existing ckprompt suite against the upgrade before adding capabilities. -List the isolated module graph to confirm PromptKit v0.14.0 and ConfigKit v0.7.1. -Record baseline failures, and repair genuine upgrade regressions. The composed -negative PromptKit diff test remains valid until Stage 3 enables the capability; -its replacement belongs to Stage 9. - -For isolated test/list checks after preparing the disposable files, use -`GOWORK=off GOTOOLCHAIN=local`, `-modfile=`, and -`-mod=readonly`. This proves local-source compatibility, not future tag -availability. The reviewed maintainer toolchain is Go 1.26.8; do not raise the -consumer minimum to that patch version. - -**Completion evidence (2026-10-12)** - -- Updated ckprompt to PromptKit v0.14.0. `go mod download -json` confirmed the - release tag resolves to the roadmap's pinned source commit - `143c6e9b3a675872117b0471e2ff8bcb25055a54`; Go tooling supplied the module - checksums. Go 1.26.0, ConfigKit v0.7.1, and the existing CommandKit module - requirements remain unchanged. No additional indirect requirements were - needed, and the ignored workspace remains unchanged. -- Workspace-off `go test ./...` passed for both ckprompt and ckconfig with - `GOWORK=off GOTOOLCHAIN=local`, `-mod=readonly`, temporary module/sum pairs, - and local replacements only for unpublished CommandKit prerequisites. -- `GOTOOLCHAIN=local go test ./...` passed in `integrations/ckprompt` with the - workspace. The isolated ckprompt graph selected PromptKit v0.14.0 and ConfigKit - v0.7.1; the isolated ckconfig graph selected ConfigKit v0.7.1 and contained no - PromptKit module. The existing composed negative diff test passed; there were - no baseline failures. -- Full repository and final assembled-state validation remain assigned to - Stage 12. - -## Stage 2: Make engine diagnostics reusable for paired acquisition - -**Outcome:** private engine acquisition retains completed diagnostics and can -identify comparison sides without duplicating native loading logic. - -**Starting points:** `loadPromptKitEngine` and `promptKitDiagnostics` in -`integrations/ckprompt/adapters.go`; acquisition and deferred-diagnostic tests -in `adapters_test.go`. - -**Steps** - -1. Refactor the private helper to support ordinary and comparison-side diagnostic - headings. Keep the existing ordinary scope heading; comparison headings - identify scope `promptkit` and left/right. A private heading parameter/helper - is sufficient; add no public diagnostic API. -2. Continue adapting `configkit.LoadError` sources and records while preserving - supported error identity. Retain the nil-engine operational failure and - ordinary configuration inspection facets. -3. After a successful engine load, obtain its captured configuration inspection - and adapt its diagnostics before honoring cancellation observed after the - load. The current helper returns too early and loses those diagnostics. - Return collected diagnostics with the cancellation error, without starting - a later side or delivering a report. -4. Retain deferred writers, severity conversion, and the metadata copies needed - by those writers. Each side's native source IDs must remain associated with - its own source legend. -5. Preserve ordinary public callbacks and successful reports. Reuse this helper - in following stages; do not promise interruption inside synchronous inspection - or transactional output. - -**Validation and handoff** - -Extend adapter tests with a loader that returns an engine with inspection -warnings and cancels before returning. Observe cancellation identity and retained -warnings. Check ordinary headings and deferred-writer error propagation. Create -native diagnostic fixtures through public APIs; do not import upstream internals -or assert exact cancellation polling counts. - -**Completion evidence (2026-10-12)** - -- Refactored the private engine loader to collect inspection diagnostics before - checking cancellation observed after a successful load. Diagnostic headings - retain the ordinary scope form and can identify a comparison side. ConfigKit - load diagnostics and the original load error remain available. -- Added adapter coverage for post-load cancellation, ConfigKit load-error identity - and diagnostics, ordinary and comparison-side headings, and deferred-writer - error propagation. `GOTOOLCHAIN=local go test ./...` passed in - `integrations/ckprompt`. -- PromptKit v0.14.0 provides no public warning callback in engine configuration, - and its native configuration path emits no warnings. Therefore a successful - engine with inspection warnings cannot be constructed through the public API; - native warning retention across cancellation remains unexercised. The ordering - change directly retains any diagnostics if a later PromptKit version supplies - them. The selected integration evidence is otherwise complete. -- Full repository and final assembled-state validation remain assigned to - Stage 12. - -## Stage 3: Add the bundled PromptKit configuration pair provider - -**Outcome:** `ConfigScope` advertises Diff and supplies a native provider usable -by ckconfig's existing paired-input command and report path. - -**Starting points:** `ConfigScope` in ckprompt's `adapters.go`, and public -`ckconfig.Scope`, `ComparisonRequest`, and the existing ConfigKit adapter. - -**Steps** - -1. Add `ckconfig.Diff` to the bundled operations and supply `Compare` with the - existing request/state signature, returning - `commandkit.Acquired[[]configkit.Difference]`. -2. Use already prepared left/right selections and inputs. Load left then right - with the same supplied `S`, obtain both `ConfigurationInspection` views through - Stage 2's helper, and call native `left.Diff(right)`. -3. Accumulate reached-side diagnostics in order. Keep left diagnostics if right - acquisition fails and both sides' diagnostics if comparison fails. Add scope, - side, or comparison context through supported error wrapping, preserving - `errors.Is`/`errors.As` behavior. -4. Check cancellation at operation boundaries before reaching the next loader - or comparison, retaining completed diagnostics. Equal selections do not skip - reached loader calls; application caches determine whether engines are reused. -5. Keep ordinary `Acquire` and facets. Retain nil-loader construction errors even - when operations are narrowed or cleared. Callers may still replace `Compare` - or narrow capabilities before declaration capture. - -**Validation and handoff** - -Use two fast real engines with different captured configurations, comparing the -adapter's native records with the upstream result. Cover equal selections reaching -both calls, correct side inputs/shared state, left failure stopping right, -right failure retaining left diagnostics, and cancellation retaining completed -side diagnostics. Exercise reachable native failures without adding a public -comparator injection hook solely for tests. Add no reconstructed configuration -model or duplicate ckprompt comparison renderer. - -**Completion evidence (2026-10-12)** - -- `ConfigScope` now declares `ckconfig.Diff` and supplies a pair callback that - loads left then right with each side's selection/input and the shared state, - collects diagnostics in order, checks cancellation at operation boundaries, - and returns PromptKit's native `ConfigurationInspection.Diff` records. Ordinary - acquisition and the retained nil-loader issue remain available. -- Added fast native-engine adapter coverage for the PromptKit result, equal - selections reaching both loader calls, side inputs/shared state, left failure - stopping right, right ConfigKit load diagnostics and error identity, and - cancellation stopping before right load. `GOTOOLCHAIN=local go test -count=1 .` - passed in `integrations/ckprompt`. -- PromptKit v0.14.0 exposes no public way to add successful inspection warnings, - and valid engine-derived inspection views do not expose a reachable native Diff - failure. Therefore successful left-side warning retention on right failure, - both-side warning retention on native failure, and a native Diff failure are - not exercisable without adding a test-only injection path. The implementation - accumulates reached diagnostics and preserves error causes; these limits remain - recorded alongside Stage 2's warning-retention limitation. -- Installed-command verification and the composed consumer's obsolete negative - comparison expectation remain for Stages 4 and 9 respectively. - -## Stage 4: Verify comparison through installed config commands - -**Outcome:** the adapter works through public assembly, existing typed-input -preparation, and existing YAML report delivery. - -**Starting points:** ckprompt external composition tests and ckconfig comparison -coverage. New integration behavior belongs in ckprompt; retain generic coverage -with its current owner. - -**Steps** - -1. Install `ckconfig.Command` with a real `ckprompt.ConfigScope` and an app - scope for default-scope evidence; invoke `config diff --scope promptkit` - through a public `commandkit.App`. -2. Demonstrate left/right selection, omitted right inheritance, and a supplied - empty override. Apply one original captured domain selector to both separately - prepared inputs, finish both checks before shared state, and observe received - loader values. Reuse generic ckconfig preparation tests for unrelated cases. -3. Decode the report using the existing additions/changes/deletions schema; - demonstrate meaningful native changes and successful comparisons with - differences. Bare diff still defaults to `app`, and comparison with scope - `all` remains unsupported. -4. Check help/discovery reflects a narrowed operation set and that help, version, - and scope discovery acquire no engines. Clearing Diff leaves other declared - scope operations usable. -5. Verify diagnostics/error identity through an installed failure path. Reuse - generic delivery-failure coverage unless the integration exposes a distinct - gap; do not copy the comparator, parser matrix, or renderer test suite. - -**Validation and handoff** - -Run focused ckprompt comparison tests. The composed example's obsolete negative -expectation is knowingly pending Stage 9; do not report the whole suite as passing -while it remains. Keep assertions on semantic reports and supported outcomes, -not exact diagnostic snapshots or private layout. - -**Completion evidence (2026-10-12)** - -- Added external-package integration coverage that installs `ckconfig.Command` - with the real `ckprompt.ConfigScope`, an app scope, and a public - `commandkit.App`. It compares two native PromptKit engines and decodes the - existing additions/changes/deletions YAML report, including a meaningful - change. -- Verified explicit left/right selection, omitted-right inheritance, and a - supplied empty right override. The same captured campaign selector reaches - separately prepared left/right inputs; both checks finish before shared state - creation, and the provider receives those inputs and state. -- Confirmed bare diff uses the app scope, scope `all` is rejected before engine - loading, installed ConfigKit failure preserves its `LoadError` identity and - left-side diagnostic heading, and help/version/scope discovery do not load an - engine. Narrowed discovery lists only enabled operations, and Show remains - usable after Diff is cleared. -- `GOTOOLCHAIN=local go test -count=1 .` passed in `integrations/ckprompt`. - The composed example's obsolete negative expectation remains assigned to - Stage 9; no full-module pass is claimed here. - -## Stage 5: Add optional catalog providers to the public suite - -**Outcome:** either catalog can be supplied independently, and `FromEngine` -provides both using PromptKit's native APIs. - -**Starting points:** `Suite` and `FromEngine` in -`integrations/ckprompt/adapters.go`. - -**Steps** - -1. Add the accepted fields to `Suite[I, S]` exactly as selected: - - ```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) - ``` - -2. Update declaration comments for catalogs and named inspection. Document - optional callbacks and retain existing input/state zero-value and check timing - contracts. Add no catalog request wrapper. -3. Extend `FromEngine` to supply both callbacks alongside its named-inspection - callbacks. Acquire only when reached, then call `Engine.ListPrompts(ctx)` or - `Engine.ListProfiles(ctx)` through the public API. -4. Return native identities/order with acquisition diagnostics and supported - error identity. Use Stage 2's ordinary-heading acquisition helper. Do not - derive catalogs from YAML or perform named inspection/readiness loops. -5. Keep nil-loader issues attached even when callers clear all four operations. - This stage changes providers; family assembly follows in Stage 7. - -**Validation and handoff** - -Use real engines and their public listing results as the native oracle. Cover -selection/input/state forwarding, load diagnostics/errors, and cancellation. -Retain named-inspection tests. Custom empty catalogs and presentation belong to -Stage 8; do not retest PromptKit's complete membership semantics. - -**Completion evidence (2026-10-12)** - -- Added the selected optional `ListPrompts` and `ListProfiles` callbacks to - `ckprompt.Suite` with the accepted signatures, and updated its declaration and - `FromEngine` documentation to cover catalogs alongside named inspection. -- `FromEngine` now loads an engine only when a catalog callback is reached, - delegates to PromptKit's native `ListPrompts` and `ListProfiles`, and returns - the native ordered results with acquisition diagnostics. -- Adapter tests compare both results with the same engine's public native - methods and cover context/selection/input/state forwarding, ConfigKit load - diagnostic and error identity retention, cancellation after loading, and a - nil-loader issue after all four callbacks are cleared. Existing named - inspection coverage remains in place. -- `GOTOOLCHAIN=local go test -count=1 .` passed in `integrations/ckprompt`. - Family assembly and catalog presentation remain assigned to Stages 7 and 8. - -## Stage 6: Implement the catalog YAML representation - -**Outcome:** small private helpers encode the explicitly selected CLI schema. - -**Starting points:** ckprompt's existing YAML/buffered report helpers in -`command.go`. - -**Steps** - -1. Define a private prompt catalog entry with explicit `yaml:"id"` and - `yaml:"version"` string fields, without `omitempty`, populated from native - `PromptIdentity` values. Upstream struct serialization does not define the - CLI schema. -2. Encode one bare entry sequence for prompts and a bare string sequence for - profiles. Preserve provider order and exact strings, including duplicates, - whitespace, and numeric-looking versions. Let the YAML encoder quote values. -3. Normalize both nil and allocated empty successful slices to an empty sequence - rendered as `[]`, not null. Named-inspection nil-pointer failure handling - does not apply to successful catalog slices. -4. Prepare the full encoded bytes before output; Stage 7 reuses existing delivery. - Add no public report type or generic resource serialization framework. - -**Validation and handoff** - -Review the mapping to the accepted schema. Add command-boundary schema evidence -in Stage 8 once helpers are wired. Test decoded types, fields, sequence order, -and empty inventories; incidental quoting style, private names, and indentation -are not new contracts. - -**Completion evidence (2026-10-12)** - -- Added private YAML encoders that map native prompt identities to entries with - explicit string `id` and `version` fields and encode profile IDs as a bare - string sequence. Both return fully prepared bytes using the existing YAML - encoder; nil and allocated empty catalogs normalize to empty sequences. -- Unit coverage decodes prompt entries and profile values to check field names, - string types, order, duplicates, whitespace, and numeric-looking values. Nil - and allocated empty inputs both encode as `[]`. -- `GOTOOLCHAIN=local go test -count=1 .` passed in `integrations/ckprompt`. - Command-boundary schema coverage remains assigned to Stage 8; command wiring - and delivery remain assigned to Stage 7. - -## Stage 7: Assemble and execute independent catalog commands - -**Outcome:** catalog commands and optional named-show commands share existing -capture, input preparation, acquisition, and outcome mechanics. - -**Starting points:** `Command`, `newDefinitionCommand`, -`prepareDefinitionInput`, and `runDefinitionInspection` in ckprompt; -`writePromptReport` and `definitionFailure`. - -**Steps** - -1. Return absence only when all four operation callbacks are nil. Retain attached - construction errors before skipping absence. Valid absence claims no namespace; - a nonempty family retains root-only installation/collision behavior. -2. Generate `show` only with supplied named-inspection operations and `list` - only with supplied catalog operations. Generate `list prompts` and - `list profiles` independently. Empty intermediate groups/help entries vanish. -3. Capture selector metadata and callback references when `Command` is called. - Use `CaptureFlags` and original handles for `ApplyTo`, not a second parser, - internal setters, or backend objects. -4. Catalogs accept presence-aware config/overlay selection and suite selectors, - no operands, version selector, or scope selector. Default `--format` to - `yaml`; accept only `yaml` here. Preserve named-show formats/defaults. -5. Check format before runtime acquisition. Reuse or straightforwardly generalize - private input preparation: create one suite `I`, apply captured converted - selectors once, then call `CheckInput(selection, input)`. -6. After checks, when reached, initialize one suite `S` and invoke only the - selected provider. Nil factories supply zero values including nil pointers. - Do not repair caller aliases or allocate arbitrary pointer types; preserve - core-owned parsed collection independence. -7. Retain diagnostics on provider, cancellation, encoding, and delivery errors; - check cancellation at existing operation boundaries. Successful nil/empty - catalogs use Stage 6's empty-sequence path. -8. Finish encoding before delivery; reuse `writePromptReport` for failures, - short writes, and incomplete-report fields. Preserve usage/operational - classifications and supported error identity. Caller effects remain theirs. - -**Validation and handoff** - -Compile and exercise custom prompts-only/profiles-only suites. Check a successful -catalog, invalid format stopping before factories, and catalog-only help omitting -`show`. Stage 8 completes evidence. No new core public API should be necessary. - -**Completion evidence (2026-10-12)** - -- `Command` now builds `show` and `list` independently, omits absent families, - retains construction issues when all four callbacks are cleared, and captures - the caller's selectors when the command is created. Catalog commands expose - config, overlay, selectors, and YAML format without named-show arguments. -- Catalog invocation checks format before suite input preparation, applies - captured selectors once, checks the prepared input, then creates one state and - calls only the selected provider. It retains diagnostics through provider and - cancellation failures, encodes before output, and reuses existing report - delivery behavior. -- Added focused command coverage for prompts-only and profiles-only help, - catalog-only omission of `show`, successful preparation and provider input, - and invalid-format preflight before suite factories/providers. -- `GOTOOLCHAIN=local go test -count=1 .` passed in `integrations/ckprompt`. - Complete lifecycle, YAML schema, cancellation, and delivery-failure coverage - remains assigned to Stage 8. - -## Stage 8: Complete catalog invocation and presentation coverage - -**Outcome:** observable catalog contracts have focused coverage without freezing -private organization or repeating upstream suites. - -**Starting points:** ckprompt `command_test.go`, external `composition_test.go`, -and existing fake writers/public declaration helpers. - -**Steps** - -1. Cover independent callbacks, catalog-only/show-only/mixed trees, and valid - absence. Extend installation coverage only for distinct new risks. Confirm - nil-loader errors remain after all four callbacks are cleared. -2. Observe construction, installation, help, and version invoking no suite - factories/providers. Help with supplied flags still performs normal conversion. -3. Cover one input/state per reached invocation, checks before state/provider, - failed preflight/check preventing acquisition, nil-factory zero values, and - original selector identity/presence. Include representative supplied - empty/false/zero and repeatable values, plus a second run without leaked values. - Assert received data and selected lifecycle events, not private storage. -4. Decode custom-provider reports: explicit prompt `id`/`version` strings, - profile strings, no envelope, exact values/order, and nil/allocated-empty - inventories. Include numeric-looking versions, YAML-sensitive identifiers, - and deliberately unsorted entries to detect command-side reordering. -5. Check default/explicit YAML, unsupported format, and unwanted operands. - Core parsing owns unknown version/scope flags; add no special rejection parser. -6. Cover provider errors with diagnostics, cancellation after a completed - provider preventing delivery, writer errors, and short writes. Observe supported - error identity, classification, diagnostics, and incomplete delivery fields. - Reuse existing diagnostic-writer coverage. - -**Validation and handoff** - -Run focused catalog and existing named-show tests through assembled public -commands. Native membership belongs to Stage 5. Add no provider network access, -benchmark thresholds, concurrency guarantees, or general fixture framework. - -**Completion evidence (2026-10-12)** - -- Expanded assembled-command coverage for independent prompts/profiles, mixed - show/list trees, catalog-only help, existing show-only and valid-absence - behavior, and nil-loader errors after all four callbacks are cleared. -- Verified construction, installation, help, and version do not invoke suite - factories or providers. Help with a supplied selector still converts it. - Invocation tests observe one input and state after checks, usage rejection - before acquisition, nil-factory zero values, original selector capture, - supplied empty/false/zero/repeated values, and fresh values on a second run. -- Decoded command output to verify prompt `id`/`version` string fields, profile - string sequences, no envelope, exact values and order, default and explicit - YAML, and `[]` for nil and allocated-empty inventories. Extra operands and - unavailable version/scope flags fail as usage without reaching providers. -- Covered provider error identity and diagnostics, cancellation after provider - completion preventing output, report writer errors, and short writes with - incomplete-report state and retained diagnostics. -- Focused assembled catalog/named-show tests and the complete ckprompt package - suite passed with `GOTOOLCHAIN=local go test -count=1`. - -## Stage 9: Demonstrate capabilities in the composed consumer - -**Outcome:** the maintained example exercises both features through bundled -adapters, without duplicated application command infrastructure. - -**Starting points:** `integrations/ckprompt/examples/composed/main.go`, tests, -fixtures, and README. - -**Steps** - -1. Keep `ConfigScope(loadPromptEngine)` and `FromEngine(loadPromptEngine)`; - their new defaults provide comparison and catalogs. Do not reproduce commands. -2. Demonstrate PromptKit-scope diff using the existing before/after fixtures and - campaign selection through the selection-aware application loader. Adjust a - small fixture only if needed for meaningful native evidence. -3. Replace `TestPromptKitScopeDoesNotSupportConfigurationDiff` with a positive - public invocation test decoding a meaningful YAML change. Retain app comparison - and cache tests distinguishing selection and supplied campaign identity. -4. Add both catalog invocations with campaign/config selection and native - identities. Check relevant entries without pinning the entire maintained - upstream inventory. No requirement inspection or readiness loop is added. -5. Update the example README with copyable diff/catalog/named-show commands. - Preserve session restore and scope-specific domain checks. Example cache - choices are recommendations/evidence, not policy for consuming applications. - -**Validation and handoff** - -Run example tests and the complete ckprompt suite. Existing ordinary scope -operations, named reports, app comparison, and the domain command must work with -the upgraded dependency. - -**Completion evidence (2026-10-12)** - -- Replaced the obsolete negative PromptKit diff test with a public composed-app - invocation that compares the before/after fixtures using the spring selector - and decodes the native change under the spring profile. Updated the after - fixture's spring model to make that comparison meaningful. The application - diff test still checks the changed default and now also checks the model value - under an explicit spring override. -- Added composed public invocations for both catalogs with config and campaign - selection. Tests decode the YAML and find the configured `briefing` version - and selected `autumn` profile without pinning PromptKit's full catalog. -- Updated the example README with copyable PromptKit diff/catalog commands and - described how the selection-aware loader and sample cache behave. Existing - ordinary scope operations, named reports, app comparison/cache behavior, and - session command coverage remain in place. -- `GOTOOLCHAIN=local go test -count=1 .` passed in the composed example, and - `GOTOOLCHAIN=local go test -count=1 ./...` passed in `integrations/ckprompt`. - -## Stage 10: Reconcile canonical documentation and capability status - -**Outcome:** current documentation describes delivered behavior and separates -completed adoption from deferred requirement inspection. - -**Steps** - -1. Update ckprompt declarations/GoDoc and `doc.go` for providers, defaults, - narrowing, and preparation. Exact public contracts belong there. Review the - module/root READMEs for accurate orientation. -2. Update the [CLI reference](../cli.md) for both catalogs, selectors, YAML - default/schema, empty inventories, and PromptKit diff availability through - the existing comparison section. Keep named-show formats and comparison rules. -3. Update [consumer guidance](../consumers/guide.md), - [internal overview](../internal/overview.md), and development examples. - Explain all four `FromEngine` callbacks and `ConfigScope`'s Diff plus ordinary - operations. Show narrowing before capture; link maintained examples for full - code rather than adding another complete prose example. -4. Replace claims of absent PromptKit comparison/catalogs. Reconcile the completed - `configkit.md` summary and `deferred.md`; keep a standard `InspectRequirements` - command deferred without inventing syntax or adding it to validation/show. -5. Review architecture/ADRs for consistency; existing decisions authorize this - work. Do not revise durable records merely to duplicate fields/report details. - Report any actual authority conflict instead of strengthening policy silently. -6. Record the feature roadmap's delivered status, with final validation evidence - in Stage 12. Preserve previous implementation history links; do not restart - completed ConfigKit work. - -**Validation and handoff** - -Review diffs, links/fragments, examples, and stale statements; run documented -Markdown whitespace checks. Describe native semantics as upstream-owned. Do not -promise arbitrary catalog/provider data is safe for public disclosure. - -**Completion evidence (2026-10-12)** - -- Updated ckprompt GoDoc for native configuration comparison, all four optional - callbacks, callback narrowing, selector/input preparation, nil-factory zero - values, and catalog YAML defaults. Root and module READMEs now describe the - shipped integration. -- Updated the CLI reference for PromptKit `config diff` and independent prompt - and profile catalogs, including selectors, YAML schema/default, empty results, - and the owning-library boundary for comparison and catalog membership. It - leaves catalog data disclosure with the application/provider. -- Updated consumer guidance with a narrowing-before-capture example, the - internal package overview, and development commands. The PromptKit roadmap now - records delivered behavior; the ConfigKit roadmap summary reflects the later - PromptKit adoption; and `deferred.md` retains only requirement inspection as a - PromptKit capability deferred from this feature. -- Reviewed the architecture policy and ADRs 0004 and 0008–0012. They remain - consistent with the delivered ownership and invocation model; no decision - record changes were needed. Historical baseline and ConfigKit completion - records remain clearly scoped to their original work. -- Markdown whitespace checks passed. A local-link and fragment check passed for - all ten changed Markdown files. Composed example behavior was exercised and - passed with Stage 9's example and complete ckprompt suite checks. - -## Stage 11: Reconcile notices and prepared release notes - -**Outcome:** distributed metadata/notices match actual graphs, and unpublished -integration notes describe delivered capabilities. - -**Steps** - -1. Reconcile final ckprompt requirements/sums with Stage 1's isolated procedure. - Review other manifests for accidental workspace-induced changes. No committed - local replacements or invented prerequisite sums. -2. Update `integrations/ckprompt/docs/oss/attribution.md` to PromptKit v0.14.0 - with the roadmap's pinned source. Review upstream grant, license, notices, and - selected direct/transitive graph; change copied texts/entries where required. -3. Keep notice ownership module-local. Core notices describe its declared - ReleaseKit v0.4.0 tool; integration selection of v0.4.1 does not alter that - declaration. Preserve project grants and source-pinned links. -4. Confirm `integrations/ckprompt/docs/releases/v0.1.0.md` is still prepared and - unpublished before editing. Describe PromptKit v0.14.0, native engine-scope - diff, both catalogs, and optional selection. Remove its obsolete no-diff claim. -5. Follow independent versioning and the existing release procedure. Do not - mirror upstream versions, manufacture tags, or publish. Published notes remain - immutable: if release state changed, prepare the next appropriate unpublished - note rather than rewriting a published one. - -**Validation and handoff** - -Check graph/notice consistency, pinned links, required texts, and module-local -release/attribution URLs. Validate prose using existing procedures. No publication -exercise or new release gate is needed for this adoption sprint. - -**Completion evidence (2026-10-12)** - -- The workspace graph selected PromptKit v0.14.0, ConfigKit v0.7.1, - ReleaseKit v0.4.1, and `golang.org/x/tools` v0.49.0. PromptKit's Go module - origin confirms tag v0.14.0 resolves to the roadmap-pinned commit - `143c6e9b3a675872117b0471e2ff8bcb25055a54`. The graph's Go tools module - origin confirms v0.49.0 resolves to `18332fec72972efbb8ab9881984fec2d8cfc2b58`. -- Updated ckprompt attribution to the selected PromptKit release and source. - Inspected its released module's grant and LGPL license text; its copyright and - grant are unchanged, and it contains no separate NOTICE file. Reconciled the - stale Go tools attribution and included its applicable PATENTS notice. The - core ReleaseKit v0.4.0 declaration and notices remain unchanged; ckprompt's - graph selects v0.4.1. No module manifests or sums changed during workspace use. -- Updated the prepared ckprompt v0.1.0 note for native PromptKit comparison, - prompt/profile catalogs, named inspection, and callback narrowing, removing - the obsolete claim that PromptKit scopes lack comparison. The user confirmed - both ckprompt and ckconfig v0.1.0 tags are unpublished, so the prepared note - was eligible for revision. No release was published and no tag was changed. -- `GOTOOLCHAIN=local go list -m all` reported the graph above. `go mod download - -json` confirmed both pinned origins. Local Markdown link targets in the two - changed files exist, and `git diff --check -- '*.md' COPYRIGHT` passed. -- Stage 12's isolated graph audit found that the distributed ckprompt graph - selects `golang.org/x/tools` v0.6.0 through `golang.org/x/text` v0.14.0; - v0.49.0 was only selected in the broader workspace graph. The attribution - now follows the isolated graph and its v0.6.0 source. -- Complete repository, consumer, and isolated graph/import validation is - recorded in Stage 12 below. - -## Stage 12: Validate the complete end state and finish - -**Outcome:** features work together, distribution boundaries remain intact, and -completion evidence matches checks actually performed. - -**Steps** - -1. Format changed Go files. With the ignored workspace, run `go test ./...` in - core, ckconfig, and ckprompt separately; root traversal misses nested modules. - Include maintained consumer tests in their owning module suites. -2. Run core tests with `GOWORK=off GOTOOLCHAIN=local` and `-mod=readonly`. - Run integration suites likewise with their disposable module/sum files and - only the unpublished CommandKit replacements from Stage 1. Use `go list -m all` - for each isolated selected graph and `go list -deps -test ./...` for imported - dependencies, with the same environment/module-file flags as its test run. -3. Confirm ckprompt selects PromptKit v0.14.0 and ConfigKit v0.7.1; ckconfig - selects ConfigKit without ckprompt/PromptKit. Core has no optional integration - or owning-library dependency through production, tests, examples, or tools. - Distinguish root and integration release-tool selections. -4. From the composed example directory exercise representative invocations: - - ```sh - go run . config diff --scope promptkit --config fixtures/before.yml --against-config fixtures/after.yml - go run . promptkit list prompts --campaign spring - go run . promptkit list profiles --campaign spring --format yaml - go run . promptkit show prompt briefing --campaign spring --format yaml - go run . session restore session-42 --campaign spring - ``` - - Retain representative app diff and ordinary multi-scope inspection checks - from that example. Inspect YAML semantically; external services are unnecessary. -5. Audit every roadmap target against code, tests, docs, and notices. Resolve - implementation defects; report environmental limits honestly rather than - declaring unrun checks successful. If required validation remains blocked, - record it as pending rather than marking that check or the sprint complete. -6. Add final completion evidence here and in `promptkit.md`. Keep requirement - inspection deferred. Review documentation links/whitespace and final status, - then commit the completed nonempty unit. - -**Completion criteria** - -- Native captured PromptKit comparison uses ckconfig's existing paired preparation - and YAML delivery path, preserving reached diagnostics and error identity. -- Independent catalogs preserve native identities, render the accepted YAML, and - follow selected preparation, cancellation, diagnostic, and delivery behavior. -- Optional groups, absence, narrowing, and construction errors follow existing - installation contracts; named-show behavior remains available. -- Relevant module suites, consumers, and isolated graph/import checks pass; - any external validation limits are recorded as pending work. -- Metadata, notices, prepared notes, and canonical docs match implemented behavior. - No workspace files, local replacements, unrelated changes, or publication form - part of the sprint. - -All product/API decisions needed for this plan are settled; no open questions -remain. - -**Completion evidence (2026-10-12)** - -- `GOTOOLCHAIN=local go test ./...` passed for core, ckconfig, and ckprompt with - the local workspace. The root module includes its core example, backend, and - release-tool packages; each integration suite includes its maintained - consumer example. -- Workspace-off results for core and ckconfig used `GOWORK=off - GOTOOLCHAIN=local` and `-mod=readonly`; isolated module and package/import - enumeration also passed. The original ckprompt result did not establish - compatibility with its committed manifest: review finding - [R-5](remediation.md#r-5-validate-the-committed-ckprompt-manifest-without-an-extra-test-only-yaml-api) - found a test-only YAML v3 import requiring additional manifest tidying. -- After the R-5 import repair, fresh copied ckprompt manifests passed - `go test -count=1 ./...`, `go list -m all`, and `go list -deps -test ./...` - with `GOWORK=off GOTOOLCHAIN=local` and `-mod=readonly` on Go 1.26.8. These - copies added only temporary replacements for unpublished core/ckconfig - prerequisites, were not tidied, and retained their exact manifest/sum bytes - throughout validation. Distributed metadata needed no changes. The results - prove compatibility with local prerequisite sources, not future tag - availability. -- The isolated ckprompt graph selects PromptKit v0.14.0 and ConfigKit v0.7.1; - ckconfig selects ConfigKit v0.7.1 without ckprompt or PromptKit. Core imports - neither optional integration nor ConfigKit/PromptKit through production, - tests, examples, or tools. Core declares ReleaseKit v0.4.0, while both - integration graphs select v0.4.1. The isolated ckprompt graph selects - `golang.org/x/tools` v0.6.0 through `golang.org/x/text` v0.14.0; its notice - now follows that graph rather than the broader workspace selection. -- All seven composed example commands passed: PromptKit comparison, app - comparison, prompt and profile catalogs, named prompt inspection, session - restore, and ordinary multi-scope validation. The YAML output showed the - fixture's native PromptKit additions/change/deletion, exact catalog values, - and named prompt fields; the session command returned its synthetic session. - No external service was used. -- Audited the completed target against implementation, focused tests, canonical - docs, examples, and module-local notices. Requirement inspection remains - deferred. The Stage 2 limitation remains recorded: PromptKit v0.14.0 exposes - no public path to produce successful engine inspection warnings, so native - warning retention could not be exercised. -- `git diff --check -- '*.md' COPYRIGHT` and the local Markdown link check for - changed documentation passed. No workspace files, replacements, or module - graph artifacts are tracked; no release was published or tagged. diff --git a/docs/roadmap/promptkit.md b/docs/roadmap/promptkit.md deleted file mode 100644 index efb45cc..0000000 --- a/docs/roadmap/promptkit.md +++ /dev/null @@ -1,384 +0,0 @@ -# Adopt PromptKit v0.14.0 and expose comparison and catalogs - -Status: PromptKit v0.14.0 comparison and catalogs are implemented, documented, -and validated. All work and final evidence are in the -[implementation record](implementation.md), Stages 1–12. - -## 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. The -[implementation plan](implementation.md) assigns the ordered work and records -stage completion evidence. - -## Baseline at 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 were future capabilities at this baseline. The later adoption delivers them; requirement inspection remains deferred in [deferred.md](deferred.md). | - -## Delivered status - -The current repository uses PromptKit v0.14.0. `ConfigScope` declares native -comparison through `config diff`; `FromEngine` supplies prompt/profile catalog -and named-inspection callbacks; and `Command` installs only the supplied `list` -and `show` operations. The maintained composed consumer exercises comparison, -both catalogs, named inspection, and its application-owned session command. -Stages 1–12 and final validation evidence are recorded in the -[implementation plan](implementation.md). Requirement inspection remains -deferred. - -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 invocations 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. -Capture completed inspection diagnostics before honoring cancellation observed -after a successful load. Use 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. - -## Selected implementation scope - -The sections below record the scope selected for adoption. Implementation status -and evidence are tracked in the [implementation plan](implementation.md). - -### 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. -- 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. The [implementation plan](implementation.md) owns the validation - assignments and evidence. - -## 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. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md deleted file mode 100644 index 47baba2..0000000 --- a/docs/roadmap/remediation.md +++ /dev/null @@ -1,332 +0,0 @@ -# CommandKit implementation review remediation - -Status: all six findings are complete. This document -tracks required follow-up work and its completion evidence. - -## ConfigKit review baseline and scope - -Reviewed the ConfigKit adoption/comparison sprint, commits `c883c64` through -`28aa3b0`, against the [feature roadmap](configkit.md), completed -[implementation plan](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md), accepted ADRs, and -[architecture policy](../policy/architecture.md). The review covered changed -production code, tests, maintained examples, current documentation, module -metadata, and attribution/release-note changes. Findings below concern the -current source at `28aa3b0`. - -This was a static review using source, graph relationships, diffs, and committed -validation evidence. No Go tests or benchmarks were run during this review. -The implementation plan records the sprint's workspace and isolated-module -validation; that is prior evidence, not a new test run. - -## ConfigKit architecture assessment - -The requested architectural components are present: - -| Responsibility | Implementation evidence | -| --- | --- | -| Core remains independent of optional integrations and owning libraries; Cobra/pflag remain behind the internal adapter. | [Core manifest](../../go.mod), [internal overview](../internal/overview.md), and unchanged core/backend implementation during this sprint. | -| ckconfig captures independent comparison capabilities and validates only the providers required by declared operations. | [Scope contracts](../../integrations/ckconfig/contracts.go) and [family assembly](../../integrations/ckconfig/family.go). | -| Comparison uses inherited selections, separately prepared typed inputs, and one shared state after both checks. | [Input preparation](../../integrations/ckconfig/input.go) and [operation execution](../../integrations/ckconfig/operations.go). | -| The typed ConfigKit adapter retains its configuration type, invokes the supplied loader for reached sides, and calls native Diff with retained diagnostics. | [ConfigKit adapter](../../integrations/ckconfig/configkit_adapter.go). | -| ckconfig presents native safe right-side regions in the selected YAML report and uses existing outcomes and delivery handling. | [Renderer](../../integrations/ckconfig/diff_report.go) and [comparison execution](../../integrations/ckconfig/diff.go). | -| ckprompt adopts the shared dependency without declaring PromptKit comparison; caches and domain behavior remain application-owned. | [ckprompt manifest](../../integrations/ckprompt/go.mod), [engine scope adapter](../../integrations/ckprompt/adapters.go), and [composed consumer](../../integrations/ckprompt/examples/composed/main.go). | - -No missing architectural component or production restriction beyond the selected -scope was identified. The strengthened claims found in documentation and tests -are recorded below. The accepted exceptional whole-root empty/null ambiguity, -YAML-only format, single-scope comparison, nil-factory zero values, and -caller-owned aliases/caches are deliberate choices and require no remediation. - -## R-1: Avoid repeated full scans when assembling wide report mappings - -**Status:** Complete. **Priority:** Medium. **Category:** Code quality / efficiency. - -**Evidence:** [diff_report.go](../../integrations/ckconfig/diff_report.go), -`placeYAMLValue` and `mappingKeyIndex` (lines 59 and 98 at the review baseline). -Every inserted path component scans the existing YAML mapping's key/value -content. For N distinct added or changed sibling keys, locating those keys -performs `0 + 1 + ... + (N - 1)` key comparisons. This introduces quadratic -lookup work for legitimate wide configuration maps, in addition to the necessary -snapshot parsing and encoding. Shared ancestors can incur the same repeated -scans. - -**Required work:** Use a small report-local lookup index for assembled mapping -nodes, or an equivalently simple approach that avoids scanning all previously -inserted siblings for each placement. Keep YAML node content in insertion order; -preserve native region boundaries, string keys, root replacement, and current -assembly failure handling. Do not introduce a global cache, public renderer API, input -limits, or a new performance guarantee. - -**Completion evidence:** Review shows sibling lookup no longer repeatedly scans -the accumulated mapping. Existing semantic-path, YAML-type, ordering, and native -safe-value behavior remains intact. Any additional measurement should be focused -on this lookup cost; a numerical performance gate is not required. - -**Completed 2026-10-12:** A private, report-local `yamlValuePlacer` now indexes -each encountered mapping once and updates that index as keys are appended. -Subsequent placements reuse key positions while YAML content keeps insertion -order. Root values, native regions, and incompatible-ancestor failures retain -their handling. Existing helper tests use the same placer across placements. -`go test ./...` passed in `integrations/ckconfig`, including the simple consumer; -the diff and whitespace review passed. No public API, limits, global cache, -benchmark, or performance gate was added. - -## R-2: Scope CLI guarantees to the actual provider and delivery boundaries - -**Status:** Complete. **Priority:** Medium. **Category:** Inadvertently strengthened -contracts / documentation accuracy. - -**Evidence:** The [comparison CLI reference](../cli.md#compare-configuration-selections) -says selections are independently loaded, both reached sides are loaded, and -comparison diagnostics identify a side and source legend (lines 235, 243, and -283 at the review baseline). Those loading and diagnostic adaptation behaviors -belong to `FromConfigKit`/`AppCommand`. A custom `Scope.Compare` callback receives -the prepared pair and shared state; its loading, caching, and diagnostic effects -remain caller-owned under [ADR 0008](../adr/0008-semantic-configuration-diff.md) -and [ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). -[runConfigDiff](../../integrations/ckconfig/diff.go) forwards the callback's -diagnostics without adding side headings or enforcing its loading strategy. - -The same CLI section says cancellation leaves report output empty (line 286). -The implementation checks cancellation before delivery, then calls the supplied -writer. Cancellation during that call cannot retract bytes already delivered -and may produce partial output or a successful completed write. The selected -contract promises boundary checks, not atomic delivery or interruption inside -synchronous collaborators. - -**Required work:** - -- Describe the generic operation as preparing two selections and invoking the - declared pair provider. Attribute loader calls, their left/right ordering, and - native diagnostic side/source adaptation to the bundled ConfigKit adapter. - Equal selections alone must not cause CommandKit to skip the provider; this - does not guarantee a physical reload or prohibit application caches. -- State that preparation failures and cancellation observed before delivery - starts leave CommandKit's report output empty. Once writing starts, the - existing write-error/short-write and incomplete-report handling applies; - caller writers and callbacks retain their own effects. - -**Completion evidence:** The CLI reference accurately describes both bundled -adapters and custom pair providers, and makes no transactional cancellation or -writer-interruption guarantee. Correct the prose rather than expanding runtime -enforcement or imposing new requirements on consumers. - -**Completed 2026-10-12:** The CLI reference now describes preparation and provider -invocation generally, attributes ordered loader calls and native diagnostic -adaptation to the bundled ConfigKit adapters, and preserves custom provider and -application cache ownership. Empty report output is promised only for report -preparation failure or cancellation observed before delivery starts. Writer -interruption and rollback are not promised. The prose was checked against the -adapter and report execution paths; local links and whitespace checks passed. -No runtime enforcement or consumer requirement was added. - -## R-3: Make preparation tests reject failure without freezing private storage - -**Status:** Complete. **Priority:** Medium. **Category:** Test quality / -inadvertently strengthened implementation invariants. - -**Evidence:** In -[comparison_preparation_test.go](../../integrations/ckconfig/comparison_preparation_test.go): - -- `TestComparisonPreparesEqualSelectionsWithSeparateTypedInputs` rejects only - `OutcomeUsage` (line 96). An operational failure after the observed input/state - work can pass, despite this being a valid successful comparison scenario. -- `TestComparisonPlanStoresPairSeparatelyFromOrdinaryInputs` (line 114) requires - `plan.comparison` and an empty `plan.scopes`, and reads the request directly - from that representation. A correct internal refactor storing the same checked - pair differently fails this test without violating the public lifecycle or - provider contract. The implementation plan explicitly leaves private storage - and equivalent refactoring as implementation choices. - -**Required work:** Require `OutcomeSuccess` in the valid equal-selection case. -Replace or consolidate the storage-layout test with observations through the -assembled comparison callback: correct side selections and typed inputs, both -checks before shared state/provider execution, and ordinary acquisition unused. -Retain the selected presence, conversion, collection ownership, zero-value, and -failure-classification protection. Do not add a blanket ban on private helper -tests or require arbitrary factory-returned objects to be distinct. - -**Completion evidence:** A valid comparison returning an operational failure is -rejected by the test. Tests protect the paired provider/lifecycle contract -without requiring a particular private plan layout. Reuse existing behavioral -coverage where it already proves the relevant fact. - -**Completed 2026-10-12:** The valid equal-selection test now requires -`OutcomeSuccess`, so an operational failure cannot pass. The storage-layout test -was replaced with an assembled invocation that observes the provider request, -correlates each input with its checked selection, verifies both checks precede -shared state and provider execution, and verifies ordinary acquisition is unused. -It does not inspect the private plan or assign particular factory IDs to sides. -Existing presence, conversion, collection ownership, zero-value, alias, and -failure-classification cases remain. `go test ./...` passed in -`integrations/ckconfig`, including the simple consumer; formatting, diff, and -whitespace review passed. - -## R-4: Reconcile the feature roadmap's completion status - -**Status:** Complete. **Priority:** Low. **Category:** Documentation divergence. - -**Evidence:** [configkit.md](configkit.md) still says distribution reconciliation -and final validation remain outstanding in its opening status and Implementation -record (lines 4 and 350 at the review baseline). The -[implementation plan](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/20e19b95694f7fdfd5c342ec4d543152986623dc/docs/roadmap/implementation.md#stage-12-reconcile-manifests-notices-and-pending-integration-release-notes) -marks both those stages complete and records their evidence. The feature roadmap -therefore contradicts the completed sprint and can prompt agents to restart -completed work. - -**Required work:** Mark the selected feature end state complete in both passages -and link to the completed implementation evidence. Preserve the distinction -between implementation validation and release publication, including the -recorded limitations around unpublished CommandKit dependency versions. - -**Completion evidence:** Neither passage assigns completed reconciliation or -validation work as pending. The feature roadmap, implementation record, and -deferred capabilities agree on what is implemented and what remains future work. - -**Completed 2026-10-12:** Both stale passages now record the feature's completed -end state and link to the distribution reconciliation and final validation -evidence. The feature roadmap retains the limitations of local replacements for -unpublished CommandKit dependencies and treats publication separately. The -implementation and deferred records remain consistent with this status. Relevant -local links, fragments, and documentation whitespace checks passed. - -## PromptKit review baseline and architecture - -Reviewed commits `ec4eb9d` through `f8f8d27`, relative to the planning baseline -`d825538`, against the accepted [PromptKit feature roadmap](promptkit.md), -[implementation record](implementation.md), applicable ADRs, and -[architecture policy](../policy/architecture.md). Evidence includes current -source, recent diffs, tests, canonical documentation, distribution metadata, -and fresh workspace-off module/import enumeration. Go tests and benchmarks were -not rerun; recorded sprint test results are prior evidence. - -The runtime architecture matches the selected target: - -| Responsibility | Current evidence | -| --- | --- | -| Core retains declarations, installation, dispatch, bindings, help/version, and outcomes without optional owning-library dependencies. | Unchanged core/backend code and manifest; fresh isolated graph/import checks, including tests, contain neither integration nor ConfigKit/PromptKit. | -| ckconfig retains configuration command coordination, paired typed inputs, shared state, YAML comparison rendering, and delivery. | Unchanged ckconfig implementation; its isolated graph/import checks contain no ckprompt/PromptKit. | -| ckprompt adds native PromptKit comparison through the existing scope contract. | [ConfigScope](../../integrations/ckprompt/adapters.go) loads reached sides in order, retains diagnostics and supported error identity, and calls captured inspection `Diff`; no second comparator or renderer. | -| ckprompt exposes independently optional catalogs and named inspections. | [Suite and FromEngine](../../integrations/ckprompt/adapters.go) supply the accepted callbacks; [command assembly](../../integrations/ckprompt/command.go) omits absent groups, preserves retained errors, and uses core typed bindings. | -| Catalog reports preserve provider identities/order and selected invocation behavior. | Private string-field YAML reports, nil/empty sequence handling, shared suite input preparation, and existing buffered delivery in [command.go](../../integrations/ckprompt/command.go); assembled command tests cover their public behavior. | -| Domain selectors, loaders, caches, callback effects, and process exit remain application-owned. | [Composed consumer](../../integrations/ckprompt/examples/composed/main.go), [consumer guide](../consumers/guide.md#promptkit-configuration-and-definitions), and unchanged core ownership contracts. | - -No missing runtime command or adapter component, new core/backend abstraction, -dependency reversal, or additional production restriction was identified. -Requirement inspection remains deliberately deferred. YAML-only catalogs, -explicit empty inventories, capability narrowing, nil-factory zero values, -and caller-owned aliases/caches are accepted choices requiring no remediation. - -The distribution validation gap and incidental test invariant below do require -follow-up. The recorded inability to construct successful native engine warnings -or force a native Diff failure through PromptKit v0.14.0's public API is an -acknowledged validation limitation, not a reason to add test-only public hooks. - -## R-5: Validate the committed ckprompt manifest without an extra test-only YAML API - -**Status:** Complete. **Priority:** Medium. **Category:** Distribution validation gap / -dependency consistency. - -**Evidence:** At the review baseline, -[comparison_composition_test.go](../../integrations/ckprompt/comparison_composition_test.go) -imported `gopkg.in/yaml.v3` at line 17. This import was introduced by `f7b1d2c`; -the [ckprompt manifest](../../integrations/ckprompt/go.mod) declares the existing -`go.yaml.in/yaml/v4` dependency instead. The other ckprompt reports and tests use -that existing API. The new comparison test needs only ordinary YAML decoding, -with no demonstrated need for a separate parser version. - -Fresh workspace-off enumeration from ckprompt, using disposable copies of the -committed `go.mod`/`go.sum` with only local replacements for unpublished core -and ckconfig prerequisites, fails: - -```text -go list -modfile= -mod=readonly -deps -test ./... -go: updates to go.mod needed, disabled by -mod=readonly; to update it: - go mod tidy -``` - -The environment was `GOWORK=off GOTOOLCHAIN=local`. Tidying only the disposable -files adds a direct `gopkg.in/yaml.v3 v3.0.1` requirement and a `gopkg.in/check.v1` -checksum, after which the enumeration succeeds. No repository manifest was -changed during this review. Core and ckconfig pass the corresponding checks -without that extra tidy. Listing the ckprompt module graph alone succeeds, so -that narrower check does not establish package/test graph completeness. - -[Stage 12's completion evidence](implementation.md#stage-12-validate-the-complete-end-state-and-finish) -records successful read-only isolated tests and import enumeration. Those results -do not demonstrate that the committed manifest supports the same checks with -only prerequisite replacements: a tidied disposable manifest is different -distribution metadata. - -**Required work:** - -- Use the already selected `go.yaml.in/yaml/v4` API in the new comparison test. - It supports the decoding used there and avoids an unnecessary second direct - YAML API in CommandKit's own integration. This is a repair to this import, - not a prohibition on upstream dependencies using their own YAML versions. -- Reconcile legitimate requirements and real sums as needed. Keep unpublished - CommandKit replacements out of distributed files. Do not remove legitimate - transitive YAML v3 notices or metadata merely because this direct import goes - away. -- Repeat isolated checks from fresh copies of the final committed manifests, - adding only the unpublished CommandKit replacements. Run import enumeration - and the relevant suite with `-mod=readonly`; do not silently tidy validation - inputs into a graph that is absent from distribution. -- Record corrected completion evidence, distinguishing committed-metadata - compatibility from local replacement/tag availability limitations. - -**Completion evidence:** Fresh copied manifests plus only prerequisite -replacements pass `go list -deps -test ./...` and the ckprompt suite in -workspace-off read-only mode. The test uses the existing YAML API, and any -necessary metadata changes are tracked with accurate validation evidence. - -**Completed 2026-10-12:** The comparison consumer test now uses the already -declared `go.yaml.in/yaml/v4` API. Fresh copies of the distributed ckprompt -`go.mod` and `go.sum`, augmented only with replacements for unpublished core and -ckconfig prerequisites, passed `go list -m all`, `go list -deps -test ./...`, and -`go test -count=1 ./...` with `GOWORK=off GOTOOLCHAIN=local` and `-mod=readonly` -on Go 1.26.8. The suite includes the composed consumer. Validation performed no -tidy; both disposable files remained byte-for-byte unchanged after the checks. -Distributed manifests, sums, and legitimate transitive YAML v3 notices needed -no changes. Stage 12 now records this corrected committed-metadata evidence; -local replacements establish source compatibility, not unpublished tag -availability. Formatting and documentation checks passed. - -## R-6: Test comparison capability membership rather than its slice position - -**Status:** Complete. **Priority:** Low. **Category:** Inadvertently strengthened -test invariant. - -**Evidence:** At the review baseline, -[adapters_test.go](../../integrations/ckprompt/adapters_test.go), -`TestConfigScopeCompareUsesNativeDiffAndLoadsBothEqualSelections`, line 165, -required `scope.Operations[4] == ckconfig.Diff`. The accepted requirement is that -the bundled scope supports its ordinary operations and comparison; it does not -assign Diff a public position in the returned declaration slice. - -[captureSuite and normalizeOperations](../../integrations/ckconfig/family.go) -already normalize declared capability membership into the installed order. -Reordering the same operations returned by the adapter can therefore preserve -installed commands and discovery output while failing this assertion. This -turns an incidental adapter layout into a restriction on valid refactoring. - -**Required work:** Check that `Compare` is supplied and the required capabilities -are present without depending on their positions. Retain native-result, -reached-side loader, input, and shared-state assertions. This does not remove -the selected left-before-right loading requirement or any expressly selected -operator ordering contract. - -**Completion evidence:** The test still rejects missing comparison wiring or -capabilities, but accepts an equivalent ordering of the same declared operations. -It introduces no new public ordering guarantee or unrelated runtime changes. - -**Completed 2026-10-12:** The adapter test now checks comparison wiring and -membership of the five required capabilities using `slices.Contains`, without -requiring a particular position or slice length. Native-result, side-input, -shared-state, and ordered-loader assertions remain intact. Temporary Go overlays -confirmed that the focused test accepts reordered capabilities and rejects -missing Diff or a missing comparison provider. The full ckprompt suite, -including its composed consumer, passed with `GOWORK=off GOTOOLCHAIN=local`, -`-mod=readonly`, and `-count=1`, using fresh copied manifests with only local -prerequisite replacements. Production code and module metadata were unchanged; -the overlays were not retained. Formatting and documentation checks passed.