Document configuration comparison behavior
This commit is contained in:
57
docs/cli.md
57
docs/cli.md
@@ -230,6 +230,63 @@ environment-variable name; effective and historical secret fragments remain
|
|||||||
redacted. Empty location, inheritance, history, reason, and dependency lists are
|
redacted. Empty location, inheritance, history, reason, and dependency lists are
|
||||||
serialized as `[]`.
|
serialized as `[]`.
|
||||||
|
|
||||||
|
### Compare configuration selections
|
||||||
|
|
||||||
|
`config diff` compares two independently loaded selections for one scope that
|
||||||
|
declares comparison. The default scope is `app`; `--scope all` is unsupported.
|
||||||
|
The PromptKit engine scope does not currently declare comparison, so selecting
|
||||||
|
`--scope promptkit` is a usage error.
|
||||||
|
`--config` and `--overlay` select the left side. `--against-config` and
|
||||||
|
`--against-overlay` independently override the right side. When a right-side
|
||||||
|
field is omitted, it inherits the corresponding left value and supplied state;
|
||||||
|
an explicit empty string overrides it and remains supplied. Equal selections are
|
||||||
|
allowed and both reached sides are loaded.
|
||||||
|
|
||||||
|
YAML is the only format and the default. Explicit `--format yaml` is accepted;
|
||||||
|
`text` and other formats are usage errors. For example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
example config diff --config before.yml --against-config after.yml
|
||||||
|
example config diff --config base.yml --against-overlay candidate
|
||||||
|
example config diff --config base.yml --overlay current --against-overlay ""
|
||||||
|
```
|
||||||
|
|
||||||
|
ConfigKit compares frozen effective typed values after defaults and resolution;
|
||||||
|
source or provenance differences alone do not create a change. The report is one
|
||||||
|
YAML document with `additions`, `changes`, and `deletions` in that order.
|
||||||
|
Additions and changes preserve semantic paths and contain safe right-side values.
|
||||||
|
Deletions contain canonical JSON Pointer paths. Explicit null is a value; it is
|
||||||
|
not a deletion. Changed sequences and native structural replacement regions stay
|
||||||
|
atomic.
|
||||||
|
|
||||||
|
ConfigKit pairs sensitivity across both loads. A concealed change can therefore
|
||||||
|
appear even when its two safe snapshots are equal. The report omits separate
|
||||||
|
redaction and hidden-change metadata: a reported masked region changed, but that
|
||||||
|
does not mean every member inside it changed. Marker-looking public strings stay
|
||||||
|
ordinary YAML values. An empty comparison succeeds with this shape:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
additions: {}
|
||||||
|
changes: {}
|
||||||
|
deletions: []
|
||||||
|
```
|
||||||
|
|
||||||
|
The reduced report is a partial safe view, not a reloadable configuration or an
|
||||||
|
automatically applicable patch. Exceptional whole-root empty/null transitions
|
||||||
|
can be ambiguous because the report has no root envelope; ordinary field-level
|
||||||
|
null values and deletions retain their distinction.
|
||||||
|
|
||||||
|
Successful comparisons return status `0`, including concealed or empty results.
|
||||||
|
Unsupported scopes and format errors are usage errors; input checks retain the
|
||||||
|
existing usage/operational classification. Load and native comparison failures
|
||||||
|
are operational and preserve supported error identity. Comparison
|
||||||
|
diagnostics identify their left/right side and source legend. The adapter loads
|
||||||
|
left before right, retains left diagnostics if right loading fails, and gathers
|
||||||
|
both loads' diagnostics before native comparison. The complete report is
|
||||||
|
prepared before writing. Cancellation and preparation failures leave report
|
||||||
|
output empty; an output error or short write uses the existing incomplete-report
|
||||||
|
delivery outcome.
|
||||||
|
|
||||||
## PromptKit definition inspection
|
## PromptKit definition inspection
|
||||||
|
|
||||||
Applications can install prompt and profile inspection independently with
|
Applications can install prompt and profile inspection independently with
|
||||||
|
|||||||
@@ -103,18 +103,21 @@ values.
|
|||||||
|
|
||||||
Use `ckconfig.Command(ckconfig.Suite[I, S]{...})` when the application needs
|
Use `ckconfig.Command(ckconfig.Suite[I, S]{...})` when the application needs
|
||||||
multiple named scopes, selector flags, scope-aware input checks, or shared
|
multiple named scopes, selector flags, scope-aware input checks, or shared
|
||||||
acquisition state. Input is initialized separately for each selected scope;
|
acquisition state or a custom comparison provider. A declared `Diff` capability
|
||||||
state is shared by selected acquisitions. Factory results remain caller-owned,
|
uses `Scope.Compare`; `ckconfig.FromConfigKit` and `AppCommand` provide the
|
||||||
so separate initialization calls do not guarantee distinct objects. See
|
ConfigKit-backed implementation. Each comparison side gets its own initialized
|
||||||
|
and checked input, while state is shared by the invocation. Factory results
|
||||||
|
remain caller-owned, so separate initialization calls do not guarantee distinct
|
||||||
|
objects. See
|
||||||
[ckconfig.Suite's GoDoc](../../integrations/ckconfig/contracts.go) for factory
|
[ckconfig.Suite's GoDoc](../../integrations/ckconfig/contracts.go) for factory
|
||||||
timing, omitted-factory zero values (including nil pointers), and ownership.
|
timing, omitted-factory zero values (including nil pointers), and ownership.
|
||||||
The application owns the state type and what it caches. `ckconfig.FromConfigKit`
|
The application owns the state type and what it caches. `ckconfig.FromConfigKit`
|
||||||
adapts a typed ConfigKit loader without calling it during construction.
|
adapts a typed ConfigKit loader without calling it during construction.
|
||||||
|
|
||||||
The `config` family provides scope discovery, validation, native effective YAML,
|
The `config` family provides scope discovery, validation, native effective YAML,
|
||||||
source inventory, and path explanation for the capabilities declared by its
|
source inventory, path explanation, and ConfigKit-backed comparison for the
|
||||||
scopes. The [CLI reference](../cli.md#configuration-scopes) owns operator
|
capabilities declared by its scopes. The [CLI reference](../cli.md#configuration-scopes)
|
||||||
syntax and report details.
|
owns operator syntax and report details.
|
||||||
|
|
||||||
## PromptKit configuration and definitions
|
## PromptKit configuration and definitions
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,9 @@ external services:
|
|||||||
```sh
|
```sh
|
||||||
go run ./examples/core workspace greet --count=0 --tag=first --tag second
|
go run ./examples/core workspace greet --count=0 --tag=first --tag second
|
||||||
(cd integrations/ckconfig/examples/simple && go run . config show)
|
(cd integrations/ckconfig/examples/simple && go run . config show)
|
||||||
|
(cd integrations/ckconfig/examples/simple && go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml)
|
||||||
(cd integrations/ckprompt/examples/composed && go run . config validate --scope all --campaign spring --limit=0)
|
(cd integrations/ckprompt/examples/composed && go run . config validate --scope all --campaign spring --limit=0)
|
||||||
|
(cd integrations/ckprompt/examples/composed && go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml)
|
||||||
(cd integrations/ckprompt/examples/composed && go run . promptkit show prompt briefing --campaign spring --format yaml)
|
(cd integrations/ckprompt/examples/composed && go run . promptkit show prompt briefing --campaign spring --format yaml)
|
||||||
(cd integrations/ckprompt/examples/composed && go run . session restore session-42 --campaign spring)
|
(cd integrations/ckprompt/examples/composed && go run . session restore session-42 --campaign spring)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -40,10 +40,11 @@ Cobra and pflag imports remain inside this package.
|
|||||||
## Optional modules
|
## Optional modules
|
||||||
|
|
||||||
`integrations/ckconfig` owns ConfigKit adaptation, scope capture, the standard
|
`integrations/ckconfig` owns ConfigKit adaptation, scope capture, the standard
|
||||||
`config` command family, and native validate/show/sources/explain reports. It
|
`config` command family, and native validate/show/sources/explain/diff behavior.
|
||||||
depends on the public core facade and ConfigKit; it does not depend on PromptKit.
|
It depends on the public core facade and ConfigKit; it does not depend on
|
||||||
Each selected scope receives an independently initialized input, while one
|
PromptKit. Each selected scope or comparison side receives an independently
|
||||||
suite-owned state value is shared by selected acquisitions in that invocation.
|
initialized input, while one suite-owned state value is shared by an invocation's
|
||||||
|
acquisitions or comparison callback.
|
||||||
|
|
||||||
`integrations/ckprompt` owns PromptKit engine loading, configuration-scope
|
`integrations/ckprompt` owns PromptKit engine loading, configuration-scope
|
||||||
adaptation, and optional named prompt/profile inspection. It uses public core
|
adaptation, and optional named prompt/profile inspection. It uses public core
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Adopt ConfigKit v0.7.1 and expose native configuration comparison
|
# Adopt ConfigKit v0.7.1 and expose native configuration comparison
|
||||||
|
|
||||||
Status: end-state decisions selected; dependency adoption and `config diff` are
|
Status: ConfigKit v0.7.1 adoption and ConfigKit-backed `config diff` are
|
||||||
not implemented. This roadmap defines the selected target and remaining gap;
|
implemented. Distribution reconciliation and final validation remain in the
|
||||||
the [implementation plan](implementation.md) owns stages and execution order.
|
[implementation plan](implementation.md), which records the evidence and order.
|
||||||
|
|
||||||
## Purpose and authority
|
## Purpose and authority
|
||||||
|
|
||||||
@@ -34,14 +34,15 @@ disclosure; CommandKit owns selection, coordination, adaptation, and presentatio
|
|||||||
| Owner | Current state |
|
| 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. |
|
| 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.5.0. `Scope`, `Suite`, `FromConfigKit`, and `AppCommand` expose scopes/validate/show/sources/explain. No comparison operation or provider exists. |
|
| `integrations/ckconfig` | Requires ConfigKit v0.7.1. `Scope`, `Suite`, `FromConfigKit`, and `AppCommand` expose independently declared validate/show/sources/explain/diff capabilities. |
|
||||||
| `integrations/ckprompt` | Directly requires ConfigKit v0.5.0 and PromptKit v0.12.0. Depends on ckconfig's public scope contracts and adapts engine configuration plus named definitions. |
|
| `integrations/ckprompt` | Requires ConfigKit v0.7.1 and PromptKit v0.12.0. It depends on ckconfig's public scope contracts and adapts engine configuration plus named definitions; its ConfigKit scope does not declare comparison. |
|
||||||
| Deferred comparison | [DIFF-01](deferred.md#diff-01-semantic-configuration-comparison) records the target. Native semantics, selection syntax, provider representation, and the YAML-only report are selected; implementation remains pending. |
|
| Comparison status | ConfigKit-backed `config diff` is implemented. The [CLI reference](../cli.md#compare-configuration-selections), integration GoDoc, and [implementation record](implementation.md) own current contracts and evidence. PromptKit comparison remains deferred. |
|
||||||
|
|
||||||
The existing ConfigKit adapter acquires a typed `*configkit.Result[T]` and exposes
|
The ConfigKit adapter acquires typed `*configkit.Result[T]` values and exposes
|
||||||
its effective, source, and explanation facets through `View`. That generic
|
effective, source, and explanation facets through `View` for ordinary operations.
|
||||||
adapter is a useful place to retain typed results for comparison. `View` alone
|
Its separate comparison callback retains `T`, loads both prepared selections,
|
||||||
does not supply two results of the same `T` to `configkit.Diff`.
|
and returns the native records from `configkit.Diff` without routing through
|
||||||
|
`View`.
|
||||||
|
|
||||||
ConfigKit v0.7.1 identifies source commit
|
ConfigKit v0.7.1 identifies source commit
|
||||||
`6fffde4af8f31f99d3ee295c426eb3234cb0fb77`. Relative to the selected v0.5.0:
|
`6fffde4af8f31f99d3ee295c426eb3234cb0fb77`. Relative to the selected v0.5.0:
|
||||||
@@ -53,15 +54,14 @@ ConfigKit v0.7.1 identifies source commit
|
|||||||
runtime/API change from v0.7.0.
|
runtime/API change from v0.7.0.
|
||||||
|
|
||||||
The YAML dependency remains `go.yaml.in/yaml/v4 v4.0.0-rc.6`. Existing public
|
The YAML dependency remains `go.yaml.in/yaml/v4 v4.0.0-rc.6`. Existing public
|
||||||
loading and inspection signatures are unchanged. The review found no apparent
|
loading and inspection signatures are unchanged, and the integration suites pass
|
||||||
adapter migration requirement for existing operations; that is static review
|
with the adopted dependency. See the pinned
|
||||||
evidence, not a completed upgrade validation. See the pinned
|
|
||||||
[release notes](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/6fffde4af8f31f99d3ee295c426eb3234cb0fb77/docs/releases/v0.7.1.md)
|
[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).
|
and [comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/6fffde4af8f31f99d3ee295c426eb3234cb0fb77/docs/config.md#effective-configuration-diffs).
|
||||||
|
|
||||||
## Dependency adoption and ownership
|
## Dependency adoption and ownership
|
||||||
|
|
||||||
Both integration modules select ConfigKit v0.7.1 and carry normal dependency
|
Both integration modules now select ConfigKit v0.7.1 and carry normal dependency
|
||||||
metadata for their actual graphs. Consumer Go minimums remain 1.26.0, the selected
|
metadata for their actual graphs. Consumer Go minimums remain 1.26.0, the selected
|
||||||
release toolchain remains 1.26.8, and PromptKit remains v0.12.0 for this work.
|
release toolchain remains 1.26.8, and PromptKit remains v0.12.0 for this work.
|
||||||
Core continues to have no ConfigKit or optional-integration dependency.
|
Core continues to have no ConfigKit or optional-integration dependency.
|
||||||
@@ -115,7 +115,7 @@ empty diff without an invented requirement that an override be supplied. Do not
|
|||||||
short-circuit acquisition merely because the selections are equal: caller-owned
|
short-circuit acquisition merely because the selections are equal: caller-owned
|
||||||
loading may produce different effective results.
|
loading may produce different effective results.
|
||||||
|
|
||||||
For example, these show the accepted target syntax, not current commands:
|
For example, these are current invocations:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
app config diff --config before.yml --against-config after.yml
|
app config diff --config before.yml --against-config after.yml
|
||||||
@@ -255,12 +255,12 @@ boundaries; do not promise interruption inside a synchronous upstream call.
|
|||||||
|
|
||||||
### Comparison provider and ConfigKit adapters
|
### Comparison provider and ConfigKit adapters
|
||||||
|
|
||||||
Add a narrow optional comparison callback to `ckconfig.Scope[I, S]`. Its request
|
`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
|
groups each side's selection with its separately prepared typed input and supplies
|
||||||
one shared state value separately. Return
|
one shared state value separately. Return
|
||||||
`commandkit.Acquired[[]configkit.Difference]` plus an error, following the existing
|
`commandkit.Acquired[[]configkit.Difference]` plus an error, following the existing
|
||||||
acquisition convention. Reuse upstream public record types rather than duplicate
|
acquisition convention. It reuses upstream public record types rather than
|
||||||
them solely to rename fields. The selected target shape in ckconfig is:
|
duplicating them solely to rename fields. The current API shape is:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type ComparisonSide[I any] struct {
|
type ComparisonSide[I any] struct {
|
||||||
@@ -273,13 +273,13 @@ type ComparisonRequest[I any] struct {
|
|||||||
Right ComparisonSide[I]
|
Right ComparisonSide[I]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accepted target field on Scope[I, S]:
|
// Current field on Scope[I, S]:
|
||||||
// Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error)
|
// Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error)
|
||||||
```
|
```
|
||||||
|
|
||||||
These names and the callback shape are selected for implementation; they are not
|
These are the implemented exports in `integrations/ckconfig/contracts.go`.
|
||||||
implemented exports. ADR 0012 records paired provider ownership and input/state
|
ADR 0012 records paired provider ownership and input/state lifetimes; GoDoc owns
|
||||||
lifetimes; this roadmap owns the target declarations until the Go API is implemented.
|
the exact public declarations.
|
||||||
|
|
||||||
`AppCommand` and `FromConfigKit` provide native comparison alongside their existing
|
`AppCommand` and `FromConfigKit` provide native comparison alongside their existing
|
||||||
supported operations, with ordinary capability narrowing available. They use the
|
supported operations, with ordinary capability narrowing available. They use the
|
||||||
@@ -306,19 +306,18 @@ or loads need not run after failure. Declaration construction, installation, hel
|
|||||||
version, and scope discovery leave input/state factories and acquisition/comparison
|
version, and scope discovery leave input/state factories and acquisition/comparison
|
||||||
callbacks uninvoked.
|
callbacks uninvoked.
|
||||||
ADR 0012 records this two-selection specialization of ADR 0011's suite lifecycle,
|
ADR 0012 records this two-selection specialization of ADR 0011's suite lifecycle,
|
||||||
and the architecture policy reflects it. Document the exact implemented API
|
and the architecture policy reflects it. The exact API contract is in the Go
|
||||||
contract in Go declarations and GoDoc when it lands.
|
declarations and GoDoc.
|
||||||
|
|
||||||
### Application-owned state and caches
|
### Application-owned state and caches
|
||||||
|
|
||||||
Generic result handling stays inside the owning adapter, without reflection,
|
Generic result handling stays inside the owning adapter, without reflection,
|
||||||
private-core access, or result type assertions. Shared state supports consumer
|
private-core access, or result type assertions. Shared state supports consumer
|
||||||
caches whose keys distinguish the effective selections and any typed-input values
|
caches whose keys distinguish the effective selections and any typed-input values
|
||||||
that affect loading. A cache
|
that affect loading. A cache that stores only one configuration can incorrectly
|
||||||
that stores only one configuration can incorrectly reuse the left result for the
|
reuse the left result for the right and report equality. The composed example
|
||||||
right and report equality. Demonstrate correct keys in the maintained example;
|
demonstrates selection- and input-aware keys; CommandKit neither supplies nor
|
||||||
CommandKit neither supplies nor repairs application caches. Cache policy and
|
repairs application caches. Cache policy and factory objects remain caller-owned.
|
||||||
factory objects remain caller-owned.
|
|
||||||
|
|
||||||
## Design tradeoffs
|
## Design tradeoffs
|
||||||
|
|
||||||
@@ -340,46 +339,15 @@ values while representing removals explicitly. Omitting empty categories would
|
|||||||
shorten output but require missing-key handling; a separate text renderer adds no
|
shorten output but require missing-key handling; a separate text renderer adds no
|
||||||
needed operator value for this delivery.
|
needed operator value for this delivery.
|
||||||
|
|
||||||
## Work needed from the baseline
|
## Implementation record
|
||||||
|
|
||||||
These work areas close the gap from the current implementation to the selected
|
Dependency adoption, capability and typed-pair preparation, native adaptation,
|
||||||
end state above. The [implementation plan](implementation.md) defines their
|
YAML reporting, end-to-end execution, and both maintained comparison examples
|
||||||
execution order and completion evidence.
|
are implemented. Current API and operator contracts belong to GoDoc, the
|
||||||
|
[CLI reference](../cli.md#compare-configuration-selections), the
|
||||||
- **Dependency adoption:** upgrade both integration requirements, reconcile sums
|
[consumer guide](../consumers/guide.md#configkit-scopes), and the example
|
||||||
and indirect/tool dependencies, and assess PromptKit v0.12.0 against the newly
|
READMEs. The [implementation plan](implementation.md) records stage-by-stage
|
||||||
selected ConfigKit version. Preserve distributed manifests without sibling
|
changes and validation; distribution reconciliation and final validation remain.
|
||||||
replacements or committed workspace files.
|
|
||||||
- **Capability and provider API:** extend ckconfig's operation/capture/validation
|
|
||||||
model for the selected comparison provider. Preserve retained adapter errors,
|
|
||||||
capability narrowing, metadata-only scopes, and validation only of bindings
|
|
||||||
used by generated commands. Do not require an ordinary acquisition provider
|
|
||||||
for a comparison-only scope if its selected pair provider is sufficient.
|
|
||||||
- **Typed preparation:** capture comparison selection metadata and applicable
|
|
||||||
selector lists once. Prepare/check the selected pair through core bindings,
|
|
||||||
with state and callback timing from the chosen lifecycle. Keep caller-owned
|
|
||||||
objects and aliases under existing ownership rules.
|
|
||||||
- **Native adaptation:** extend the typed ConfigKit adapter/convenience factory
|
|
||||||
to load the selected pair and call `configkit.Diff`. Reuse diagnostic adaptation
|
|
||||||
and ordinary error handling without introducing a generic provider framework,
|
|
||||||
global cache, or untyped result transport.
|
|
||||||
- **Command and reports:** generate the conditional `config diff` declaration,
|
|
||||||
integrate it with discovery/help, and render the chosen report contract using
|
|
||||||
native safe values. Preserve existing operation/report behavior.
|
|
||||||
- **Documentation and distribution:** update GoDoc, CLI/consumer guidance,
|
|
||||||
maintained examples, affected module notices and pinned ConfigKit links, and
|
|
||||||
relevant release notes as implementation lands. Include a maintained comparison
|
|
||||||
example that loads genuinely different selections through shared state, with
|
|
||||||
cache keys accounting for the selection and typed-input values used by its
|
|
||||||
loader. Review transitive tool notices for the actual graph. Move DIFF-01's
|
|
||||||
implemented portion out of deferred work; retain unresolved future PromptKit
|
|
||||||
comparison and unrelated proposals.
|
|
||||||
- **Validation evidence:** run each affected module's deterministic offline suite
|
|
||||||
and representative consumers. Check module/package boundaries independently
|
|
||||||
with workspace mode off. If CommandKit prerequisite versions remain unpublished,
|
|
||||||
use disposable alternate module files for local-source wiring evidence, as
|
|
||||||
described in the [development guide](../development.md#documentation-validation).
|
|
||||||
Do not fabricate future checksums or turn migration checks into permanent gates.
|
|
||||||
|
|
||||||
### Focused behavioral evidence
|
### Focused behavioral evidence
|
||||||
|
|
||||||
|
|||||||
@@ -18,29 +18,20 @@ an idea here does not select its syntax, API, priority, or delivery date.
|
|||||||
|
|
||||||
## Deferred capability targets
|
## Deferred capability targets
|
||||||
|
|
||||||
### DIFF-01: semantic configuration comparison
|
### PromptKit configuration comparison
|
||||||
|
|
||||||
Expose comparison of two independently resolved selections of one scope using
|
ConfigKit-backed `config diff` is implemented by `ckconfig` for scopes that
|
||||||
owning-library public comparison APIs. [ADR 0008](../adr/0008-semantic-configuration-diff.md)
|
declare that capability. `ckprompt.ConfigScope` does not declare comparison.
|
||||||
owns native comparison, paired safe disclosure, and the reduced default report.
|
Reassess PromptKit's supported public comparison capabilities before planning a
|
||||||
The target includes a YAML-only report of safe changed regions; completed
|
PromptKit comparison. Do not reach into ConfigKit internals or infer comparison
|
||||||
comparisons succeed whether or not they find differences.
|
semantics from rendered YAML.
|
||||||
|
|
||||||
The initial review of ConfigKit v0.5.0 and PromptKit v0.12.0 did not find the
|
### Comparison extensions
|
||||||
public comparison support needed for that target. ConfigKit v0.7.0 introduced
|
|
||||||
`configkit.Diff`, retained in v0.7.1, which supplies native comparison and paired
|
|
||||||
safe changed-region snapshots. CommandKit still uses ConfigKit v0.5.0; dependency
|
|
||||||
adoption and comparison delivery are targeted by the
|
|
||||||
[ConfigKit roadmap](configkit.md). Assess PromptKit's supported
|
|
||||||
public comparison capabilities separately. Rendered YAML and sibling internals
|
|
||||||
are not substitutes for the owning library's public comparison contract.
|
|
||||||
|
|
||||||
The ConfigKit roadmap records accepted selection syntax and the paired provider
|
Independent per-side domain selectors and an optional assertion mode remain
|
||||||
API, with lifecycle recorded in
|
unselected extensions to the delivered ConfigKit comparison. Consider them only
|
||||||
[ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). The selected report
|
for a concrete consumer need and a deliberate API/behavior decision under the
|
||||||
shape is recorded in that roadmap. Independent per-side domain selectors and
|
relevant ADRs.
|
||||||
an optional assertion mode remain outside that delivery. Add public types and
|
|
||||||
handlers with their implementation rather than exposing placeholders.
|
|
||||||
|
|
||||||
### CAT-01: PromptKit catalogs
|
### CAT-01: PromptKit catalogs
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Implement ConfigKit adoption and configuration comparison
|
# Implement ConfigKit adoption and configuration comparison
|
||||||
|
|
||||||
Status: implementation in progress; Stages 1–10 are complete.
|
Status: implementation in progress; Stages 1–11 are complete.
|
||||||
|
|
||||||
## Scope and authority
|
## Scope and authority
|
||||||
|
|
||||||
@@ -545,9 +545,20 @@ canonical owners, while future/deferred work stays clearly separate.
|
|||||||
symbols. Keep accepted ADR decision text unchanged; presentation details
|
symbols. Keep accepted ADR decision text unchanged; presentation details
|
||||||
remain in CLI/API owners rather than returning to ADRs.
|
remain in CLI/API owners rather than returning to ADRs.
|
||||||
|
|
||||||
**Completion evidence:** current operator/API/consumer owners agree with the
|
**Completion evidence — complete:** ckconfig GoDoc now describes all five
|
||||||
implemented behavior; no stale four-operation convenience claims, text-diff
|
operations, paired input lifetimes, shared state, native records, diagnostics,
|
||||||
promises, or deferred markers for delivered ConfigKit comparison.
|
and supported error identity. The ckconfig README, CLI reference, consumer guide,
|
||||||
|
internal overview, development examples, and maintained example READMEs describe
|
||||||
|
current ConfigKit comparison behavior. The CLI owner covers independent right
|
||||||
|
inheritance and supplied presence, native effective-value semantics, reduced
|
||||||
|
safe YAML categories, null/deletion, concealed regions, empty output, root
|
||||||
|
ambiguity, diagnostics, and outcome delivery. The ConfigKit feature roadmap now
|
||||||
|
records implementation status; the deferred record no longer carries ConfigKit
|
||||||
|
comparison as pending work and retains PromptKit comparison, independent per-side
|
||||||
|
domain selectors, catalogs, and other unselected ideas. The accepted ADRs were
|
||||||
|
left unchanged. Local Markdown targets/fragments and copied commands were
|
||||||
|
reviewed; a local link check and `git diff --check -- '*.md'` passed. `go doc`
|
||||||
|
was inspected for the exported comparison API.
|
||||||
|
|
||||||
## Stage 12: Reconcile manifests, notices, and pending integration release notes
|
## Stage 12: Reconcile manifests, notices, and pending integration release notes
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,12 @@ app, err := commandkit.New(identity, ckconfig.AppCommand(loadAppConfig))
|
|||||||
|
|
||||||
Use `ckconfig.Command(ckconfig.Suite[Input, State]{...})` to define named
|
Use `ckconfig.Command(ckconfig.Suite[Input, State]{...})` to define named
|
||||||
scopes, selectors, input checks, and state shared by the selected acquisitions
|
scopes, selectors, input checks, and state shared by the selected acquisitions
|
||||||
in a config invocation. `ckconfig.FromConfigKit` adapts a typed ConfigKit loader.
|
or comparison in a config invocation. `ckconfig.FromConfigKit` adapts a typed
|
||||||
The `config` command family exposes scope discovery and the validate, show,
|
ConfigKit loader. The `config` command family exposes scope discovery and the
|
||||||
sources, and explain operations supported by the declared scopes.
|
validate, show, sources, explain, and diff operations supported by the declared
|
||||||
|
scopes. Comparison returns ConfigKit's native records to the YAML report path;
|
||||||
|
the [CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections)
|
||||||
|
owns its operator details.
|
||||||
|
|
||||||
The maintained [simple example](examples/simple) shows a complete consumer.
|
The maintained [simple example](examples/simple) shows a complete consumer.
|
||||||
The [CommandKit CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#configuration-scopes)
|
The [CommandKit CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#configuration-scopes)
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ import (
|
|||||||
// FromConfigKit adapts a typed ConfigKit loader to all five native
|
// FromConfigKit adapts a typed ConfigKit loader to all five native
|
||||||
// configuration operations. The loader receives the operation's explicit
|
// configuration operations. The loader receives the operation's explicit
|
||||||
// Selection, initialized input, and shared invocation state, and runs only when
|
// Selection, initialized input, and shared invocation state, and runs only when
|
||||||
// an installed operation selects this scope. Construction and help do not call
|
// an installed operation selects this scope. Comparison invokes it separately
|
||||||
// it. A nil original loader is retained as a construction issue, even if callers
|
// for each reached side. Construction and help do not call it. A nil original
|
||||||
// later narrow the scope's operation list.
|
// loader is retained as a construction issue, even if callers later narrow the
|
||||||
|
// scope's operation list.
|
||||||
func FromConfigKit[I, S, T any](
|
func FromConfigKit[I, S, T any](
|
||||||
name, summary string,
|
name, summary string,
|
||||||
load func(context.Context, Selection, I, S) (*configkit.Result[T], error),
|
load func(context.Context, Selection, I, S) (*configkit.Result[T], error),
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ type Selection struct {
|
|||||||
Overlay commandkit.Supplied[string]
|
Overlay commandkit.Supplied[string]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operation identifies a supported configuration inspection operation.
|
// Operation identifies a supported standard configuration operation.
|
||||||
type Operation string
|
type Operation string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -42,7 +42,8 @@ type Request struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ComparisonSide groups one configuration selection with its independently
|
// ComparisonSide groups one configuration selection with its independently
|
||||||
// prepared typed input.
|
// initialized and checked typed input. The supplied-state fields of Selection
|
||||||
|
// are preserved for the scope's loader.
|
||||||
type ComparisonSide[I any] struct {
|
type ComparisonSide[I any] struct {
|
||||||
// Selection carries the explicit config and overlay inputs for this side.
|
// Selection carries the explicit config and overlay inputs for this side.
|
||||||
Selection Selection
|
Selection Selection
|
||||||
@@ -51,7 +52,8 @@ type ComparisonSide[I any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ComparisonRequest carries the earlier and later selections supplied to a
|
// ComparisonRequest carries the earlier and later selections supplied to a
|
||||||
// scope's comparison callback.
|
// scope's comparison callback. Each side has a separately prepared input; the
|
||||||
|
// callback receives shared invocation state separately.
|
||||||
type ComparisonRequest[I any] struct {
|
type ComparisonRequest[I any] struct {
|
||||||
// Left is the earlier configuration selection.
|
// Left is the earlier configuration selection.
|
||||||
Left ComparisonSide[I]
|
Left ComparisonSide[I]
|
||||||
@@ -99,7 +101,9 @@ type Scope[I, S any] struct {
|
|||||||
// invocation.
|
// invocation.
|
||||||
Acquire func(context.Context, Request, I, S) (commandkit.Acquired[View], error)
|
Acquire func(context.Context, Request, I, S) (commandkit.Acquired[View], error)
|
||||||
// Compare compares two selections for this scope using one shared state.
|
// Compare compares two selections for this scope using one shared state.
|
||||||
// It is required when Diff is declared in Operations.
|
// Its Acquired result carries native difference records and diagnostics;
|
||||||
|
// returned errors retain their supported cause identity. It is required when
|
||||||
|
// Diff is declared in Operations.
|
||||||
Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error)
|
Compare func(context.Context, ComparisonRequest[I], S) (commandkit.Acquired[[]configkit.Difference], error)
|
||||||
|
|
||||||
issues []error
|
issues []error
|
||||||
@@ -116,24 +120,28 @@ type Selector[I any] struct {
|
|||||||
// Suite declares the typed input, shared state, selectors, and configuration
|
// Suite declares the typed input, shared state, selectors, and configuration
|
||||||
// scopes used to assemble configuration commands.
|
// scopes used to assemble configuration commands.
|
||||||
//
|
//
|
||||||
// Input initialization is separate for each selected scope; state is shared
|
// Input initialization is separate for each selected ordinary scope and each
|
||||||
// by that invocation's acquisitions. Factory results and callback effects remain
|
// reached comparison side; state is shared by the invocation's acquisitions or
|
||||||
|
// comparison callback. Factory results and callback effects remain
|
||||||
// caller-owned: Command does not deep-copy arbitrary objects or repair aliases
|
// caller-owned: Command does not deep-copy arbitrary objects or repair aliases
|
||||||
// returned by factories. Core-owned repeated flag collections are copied when
|
// returned by factories. Core-owned repeated flag collections are copied when
|
||||||
// applied to separate inputs. Factories are not invoked during construction,
|
// applied to separate inputs. Factories are not invoked during construction,
|
||||||
// installation, help, version, or scope discovery, and need not run after failure.
|
// installation, help, version, or scope discovery, and need not run after failure.
|
||||||
type Suite[I, S any] struct {
|
type Suite[I, S any] struct {
|
||||||
// NewInput is called once for each selected scope reached after operation
|
// NewInput is called once for each selected ordinary scope, or once for each
|
||||||
// preflight, before applying its selectors and calling CheckInput.
|
// reached side of a comparison, after operation preflight and before applying
|
||||||
|
// selectors and calling CheckInput.
|
||||||
// If nil, input is the zero value of I, including nil for pointer types.
|
// If nil, input is the zero value of I, including nil for pointer types.
|
||||||
NewInput func() I
|
NewInput func() I
|
||||||
// NewState is called once when acquisition is reached, after all selected
|
// NewState is called once when provider execution is reached, after all
|
||||||
// inputs pass their checks. The result is shared by selected acquisitions.
|
// selected inputs pass their checks. The result is shared by selected
|
||||||
|
// acquisitions or the comparison callback.
|
||||||
// If nil, state is the zero value of S, including nil for pointer types.
|
// If nil, state is the zero value of S, including nil for pointer types.
|
||||||
NewState func() S
|
NewState func() S
|
||||||
// Selectors declares typed flags and their applicable scopes.
|
// Selectors declares typed flags and their applicable scopes.
|
||||||
Selectors []Selector[I]
|
Selectors []Selector[I]
|
||||||
// CheckInput validates one initialized scope input after applicable values are applied.
|
// CheckInput validates one initialized scope input after applicable values
|
||||||
|
// are applied. Comparison sides are checked separately with their selection.
|
||||||
CheckInput func(scope string, selection Selection, input I) error
|
CheckInput func(scope string, selection Selection, input I) error
|
||||||
// Scopes declares the configuration scopes assembled by Command.
|
// Scopes declares the configuration scopes assembled by Command.
|
||||||
Scopes []Scope[I, S]
|
Scopes []Scope[I, S]
|
||||||
|
|||||||
@@ -43,9 +43,10 @@ type preparedSuite[I, S any] struct {
|
|||||||
// Command eagerly captures a configuration suite as a root-only config family.
|
// Command eagerly captures a configuration suite as a root-only config family.
|
||||||
// It copies suite slices, retains callback references, and returns a reusable
|
// It copies suite slices, retains callback references, and returns a reusable
|
||||||
// declaration; installation does not invoke factories or providers. During an
|
// declaration; installation does not invoke factories or providers. During an
|
||||||
// inspection, it initializes input separately for each selected scope and
|
// inspection, it initializes input separately for each selected scope. A
|
||||||
// validates those inputs before acquisition. Suite documents factory timing,
|
// comparison initializes and checks both sides before creating shared state
|
||||||
// zero values, shared state, and caller ownership of returned objects.
|
// and calling the pair provider. Suite documents factory timing, zero values,
|
||||||
|
// shared state, and caller ownership of returned objects.
|
||||||
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
|
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
|
||||||
prepared := captureSuite(suite)
|
prepared := captureSuite(suite)
|
||||||
if len(prepared.scopes) == 0 {
|
if len(prepared.scopes) == 0 {
|
||||||
@@ -67,7 +68,8 @@ func Command[I, S any](suite Suite[I, S]) commandkit.Command {
|
|||||||
|
|
||||||
// AppCommand builds the state-free, input-free convenience suite for application
|
// AppCommand builds the state-free, input-free convenience suite for application
|
||||||
// configuration. The application consumer supplies only its ConfigKit loader,
|
// configuration. The application consumer supplies only its ConfigKit loader,
|
||||||
// which runs only for a selected operation after input preflight.
|
// which runs for ordinary operations and separately for each reached comparison
|
||||||
|
// side after input preflight.
|
||||||
func AppCommand[T any](load func(context.Context, Selection) (*configkit.Result[T], error)) commandkit.Command {
|
func AppCommand[T any](load func(context.Context, Selection) (*configkit.Result[T], error)) commandkit.Command {
|
||||||
var adapterLoad func(context.Context, Selection, struct{}, struct{}) (*configkit.Result[T], error)
|
var adapterLoad func(context.Context, Selection, struct{}, struct{}) (*configkit.Result[T], error)
|
||||||
if load != nil {
|
if load != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user