Record the ConfigKit upgrade and comparison plan
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
**Base Policy Version:** 1.3
|
||||
|
||||
**Last Updated**: 2026-10-10
|
||||
**Last Updated**: 2026-10-11
|
||||
|
||||
**Upstream Source:** [architecture.md](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/architecture.md)
|
||||
|
||||
@@ -134,6 +134,14 @@ and input checks before shared state initialization and provider acquisition.
|
||||
Factories need not run after a failure and remain uninvoked during construction,
|
||||
installation, help, version, and scope discovery.
|
||||
|
||||
For two-selection configuration comparison, prepare and check each side's input
|
||||
separately with its scope identity and selection, applying the same applicable
|
||||
converted selector values to both. Finish both checks before initializing shared
|
||||
state once and invoking the integration-owned pair provider under
|
||||
[ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). Required provider
|
||||
wiring follows declared capabilities; a comparison-only scope does not require
|
||||
an unrelated ordinary acquisition callback.
|
||||
|
||||
Omitted input and state factories supply the respective type's zero value,
|
||||
including nil for pointers. Caller factories and callbacks retain responsibility
|
||||
for objects they return or reference; do not promise arbitrary deep copies,
|
||||
@@ -232,8 +240,10 @@ Concrete integration needs guide provider representations under
|
||||
Native report writers and safe inspection data preserve owning-library semantics.
|
||||
Loading all selected views before report output is a `config show` decision under
|
||||
[ADR 0007](../adr/0007-native-yaml-reports.md); other inspection operations define
|
||||
their own output timing. Semantic comparison uses supported safe snapshots and
|
||||
reports sensitivity gaps under [ADR 0008](../adr/0008-semantic-configuration-diff.md).
|
||||
their own output timing. Semantic comparison delegates to supported owning-library
|
||||
comparison APIs and retains paired safe disclosure and hidden-change metadata at
|
||||
the provider boundary. Reports may present the reduced view selected by
|
||||
[ADR 0008](../adr/0008-semantic-configuration-diff.md).
|
||||
|
||||
## Scope And Non-goals
|
||||
|
||||
|
||||
438
docs/roadmap/configkit.md
Normal file
438
docs/roadmap/configkit.md
Normal file
@@ -0,0 +1,438 @@
|
||||
# Adopt ConfigKit v0.7.1 and expose native configuration comparison
|
||||
|
||||
Status: proposed feature roadmap; dependency adoption and `config diff` are not
|
||||
implemented. The targeted delivery includes both, as requested by the user.
|
||||
This document defines the selected end state; a subsequent staged
|
||||
implementation plan will define execution order.
|
||||
|
||||
## 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 current ADR alignment edits remain uncommitted for user
|
||||
review; this roadmap follows their agreed 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.5.0. `Scope`, `Suite`, `FromConfigKit`, and `AppCommand` expose scopes/validate/show/sources/explain. No comparison operation or provider exists. |
|
||||
| `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. |
|
||||
| Deferred comparison | [DIFF-01](deferred.md#diff-01-semantic-configuration-comparison) records the target. Native semantics, selection syntax (OD-1), provider representation (OD-2), and the YAML-only report (OD-3) are accepted. |
|
||||
|
||||
The existing ConfigKit adapter acquires a typed `*configkit.Result[T]` and exposes
|
||||
its effective, source, and explanation facets through `View`. That generic
|
||||
adapter is a useful place to retain typed results for comparison. `View` alone
|
||||
does not supply two results of the same `T` to `configkit.Diff`.
|
||||
|
||||
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. The review found no apparent
|
||||
adapter migration requirement for existing operations; that is static review
|
||||
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)
|
||||
and [comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/6fffde4af8f31f99d3ee295c426eb3234cb0fb77/docs/config.md#effective-configuration-diffs).
|
||||
|
||||
## Targeted end state
|
||||
|
||||
### Dependencies and module boundaries
|
||||
|
||||
Both integration modules select ConfigKit v0.7.1 and carry normal dependency
|
||||
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.
|
||||
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.
|
||||
|
||||
### Ownership
|
||||
|
||||
| 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. |
|
||||
|
||||
### ConfigKit-backed comparison
|
||||
|
||||
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
|
||||
are supported through ordinary application loading choices. Exact side selection
|
||||
and inheritance rules are accepted in OD-1 below.
|
||||
|
||||
ConfigKit-backed adapters use the same supplied typed loader for existing
|
||||
inspection and both comparison selections. They delegate equality and paired
|
||||
disclosure to `configkit.Diff`; no rendered-YAML comparison or assertion on
|
||||
mutable `Result.Config` is introduced. Convenience wiring remains simple:
|
||||
`AppCommand` and `FromConfigKit` should provide native comparison alongside their
|
||||
existing supported operations, with ordinary capability narrowing available.
|
||||
The provider representation is accepted in OD-2.
|
||||
|
||||
Declaration capture, metadata discovery, and help leave suite factories and
|
||||
acquisition/comparison callbacks uninvoked. Invocation preparation uses original
|
||||
typed binding identities and converted values, preserving explicit empty, false,
|
||||
and zero selections. Supplied values are converted through core once, including
|
||||
help paths; applying a value to both comparison inputs does not parse it twice.
|
||||
Input/state timing for the pair is part of OD-2, rather than an implicit extension
|
||||
of the existing one-selection lifecycle.
|
||||
|
||||
### 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 default report deliberately presents a reduced view under
|
||||
OD-3 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.
|
||||
|
||||
### Reports, diagnostics, and outcomes
|
||||
|
||||
Default `config diff` to one YAML document with `additions`, `changes`, and
|
||||
`deletions`, as selected in OD-3. Use existing output streams. YAML is the only
|
||||
supported report format, with explicit `--format yaml` accepted. The
|
||||
view distinguishes deletion from null but omits separate redaction and concealed-
|
||||
change metadata. Move the implemented report contract to the CLI reference.
|
||||
ADR 0008 records this reduced view while retaining native metadata at the
|
||||
provider boundary. Other commands retain their existing format defaults.
|
||||
|
||||
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.
|
||||
|
||||
## Work needed from the baseline
|
||||
|
||||
These are work areas, not numbered implementation stages. Use the accepted
|
||||
choices below to write the staged implementation plan.
|
||||
|
||||
- **Dependency adoption:** upgrade both integration requirements, reconcile sums
|
||||
and indirect/tool dependencies, and assess PromptKit v0.12.0 against the newly
|
||||
selected ConfigKit version. Preserve distributed manifests without sibling
|
||||
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 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 open choices may be silently converted into
|
||||
contracts by implementation. Publication follows the existing release procedure
|
||||
and is not performed by this planning pass.
|
||||
|
||||
## Selected report design (OD-3)
|
||||
|
||||
**Selected:** the default operator-facing output of `config diff` is a single YAML
|
||||
document with three primary keys: `additions`, `changes`, and `deletions`.
|
||||
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.
|
||||
|
||||
**Accepted edge-case treatment:** 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. Ambiguity
|
||||
in that case is acceptable to the user and is not a planning blocker. Native
|
||||
comparison records retain their distinctions; ordinary field-level null values
|
||||
and deletions retain the selected reporting rules.
|
||||
|
||||
**Accepted format and empty-category treatment:** YAML is the only report format
|
||||
for this delivery; a separate plain text report adds no needed operator value.
|
||||
Always include all three keys in the order `additions`, `changes`, `deletions`.
|
||||
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.
|
||||
|
||||
ADR 0008 records this selected presentation. Selection syntax and provider shape
|
||||
are accepted below. No significant open decisions remain for this roadmap.
|
||||
|
||||
**Alternatives considered:** a full difference envelope with left/right snapshots
|
||||
and explicit presence, redaction, and hidden-change fields preserves all native
|
||||
metadata, but is more verbose than the chosen operator view. Embedding parsed
|
||||
values in that envelope avoids YAML strings but retains the record-oriented
|
||||
layout. A right-side-only view without deletion paths cannot represent removals
|
||||
unambiguously. The selected three-category document balances configuration-shaped
|
||||
output with explicit removal reporting.
|
||||
|
||||
Omitting empty categories would shorten the report but require consumers to
|
||||
handle missing keys. A separate text report could label changes by path or group
|
||||
them into sections, but YAML already provides readable operator output; another
|
||||
renderer and presentation contract are unnecessary for this delivery.
|
||||
|
||||
## Accepted Decisions
|
||||
|
||||
### OD-1: How operators select the two sides
|
||||
|
||||
**Accepted:** 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 show the accepted target syntax, not current commands:
|
||||
|
||||
```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.
|
||||
Shared domain selector values are the initial scope;
|
||||
independent per-side domain selectors can be considered with a concrete consumer
|
||||
need, without precluding them as future API work.
|
||||
|
||||
**Alternative considered:** expose symmetric `--left-config`/`--right-config` and
|
||||
`--left-overlay`/`--right-overlay` selections, resolving each side independently.
|
||||
This makes two independent selections explicit and avoids inheritance rules. It
|
||||
adds vocabulary beside existing configuration selectors and repeats flags for
|
||||
the common single-base overlay workflow. It remains viable if symmetry is valued
|
||||
more than reuse of familiar inspection syntax.
|
||||
|
||||
### OD-2: Comparison provider and input/state lifetime
|
||||
|
||||
**Accepted:** add a narrow optional scope comparison callback receiving
|
||||
the pair's selections, separately prepared left/right typed inputs, and one
|
||||
shared state value. Group each side's selection and input in a request value to
|
||||
avoid several positional left/right arguments. Return
|
||||
`commandkit.Acquired[[]configkit.Difference]` plus an error, following the existing
|
||||
acquisition convention. Reuse upstream public record types rather than duplicate
|
||||
them solely to rename fields. The selected target shape in ckconfig is:
|
||||
|
||||
```go
|
||||
type ComparisonSide[I any] struct {
|
||||
Selection Selection
|
||||
Input I
|
||||
}
|
||||
|
||||
type ComparisonRequest[I any] struct {
|
||||
Left ComparisonSide[I]
|
||||
Right ComparisonSide[I]
|
||||
}
|
||||
|
||||
// Accepted target field on Scope[I, S]:
|
||||
// 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
|
||||
implemented exports. ADR 0012 records paired provider ownership and input/state
|
||||
lifetimes; this roadmap owns the target declarations until the Go API is implemented.
|
||||
|
||||
The typed `FromConfigKit` adapter can retain its `T`, invoke the supplied loader
|
||||
for each reached side, and call `configkit.Diff`. 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.
|
||||
|
||||
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. Help/discovery remain free of these calls.
|
||||
ADR 0012 records this two-selection specialization of ADR 0011's suite lifecycle,
|
||||
and the architecture policy reflects it. Document the exact implemented API
|
||||
contract in Go declarations and GoDoc when it lands.
|
||||
|
||||
This keeps generic result handling inside the owning adapter and preserves
|
||||
typed binding composition 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. Demonstrate correct keys in the maintained example;
|
||||
CommandKit neither supplies nor repairs application caches. Cache policy and
|
||||
factory objects remain caller-owned.
|
||||
|
||||
**Alternative considered:** acquire a comparison-capable facet with each ordinary `View`,
|
||||
then compare the two acquired facets. This shares single-side acquisition between
|
||||
all operations and may suit providers already retaining typed results behind a
|
||||
stable comparison handle. It requires a public way to establish compatibility
|
||||
between two heterogeneous facets, and can lead to type assertions or extra
|
||||
opaque-handle machinery. Consider it if representative non-ConfigKit consumers
|
||||
demonstrate enough benefit to justify that additional contract.
|
||||
@@ -21,23 +21,26 @@ an idea here does not select its syntax, API, priority, or delivery date.
|
||||
### DIFF-01: semantic configuration comparison
|
||||
|
||||
Expose comparison of two independently resolved selections of one scope using
|
||||
owning-library safe snapshots. [ADR 0008](../adr/0008-semantic-configuration-diff.md)
|
||||
owns the accepted comparison semantics, sensitivity union, and coverage-gap
|
||||
handling. The target includes text/YAML reports of differences and gaps;
|
||||
completed comparisons can succeed even when they find either.
|
||||
owning-library public comparison APIs. [ADR 0008](../adr/0008-semantic-configuration-diff.md)
|
||||
owns native comparison, paired safe disclosure, and the reduced default report.
|
||||
The target includes a YAML-only report of safe changed regions; completed
|
||||
comparisons succeed whether or not they find differences.
|
||||
|
||||
The initial review of ConfigKit v0.5.0 and PromptKit v0.12.0 did not find the
|
||||
complete public snapshot/sensitivity contract needed for that target. Reassess
|
||||
released upstream APIs when planning it; do not treat that historical review as
|
||||
a claim about newer versions. Hidden-path metadata and supported gap reasons
|
||||
must be available without fetching secrets. Rendered YAML and sibling internals
|
||||
are not substitutes for an agreed public comparison representation.
|
||||
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.
|
||||
|
||||
Comparison selection syntax, context inheritance, and report layout remain
|
||||
future design work. Earlier possibilities included right-side root/overlay
|
||||
selection, shared versus independent domain context, and an optional assertion
|
||||
mode. Those choices are unselected. Add public types and handlers when the
|
||||
capability is supported, rather than exposing placeholders.
|
||||
The ConfigKit roadmap records accepted selection syntax and the paired provider
|
||||
API, with lifecycle recorded in
|
||||
[ADR 0012](../adr/0012-typed-configuration-comparison-pairs.md). The selected report
|
||||
shape is recorded in that roadmap. Independent per-side domain selectors and
|
||||
an optional assertion mode remain outside that delivery. Add public types and
|
||||
handlers with their implementation rather than exposing placeholders.
|
||||
|
||||
### CAT-01: PromptKit catalogs
|
||||
|
||||
|
||||
Reference in New Issue
Block a user