Document captured configuration comparison

This commit is contained in:
2026-10-09 16:06:09 +00:00
parent d1c0281053
commit d039a019cb
5 changed files with 71 additions and 12 deletions

View File

@@ -30,10 +30,13 @@ func (e *Engine) InspectConfiguration() (ConfigurationInspection, error) {
// Diff compares this view's captured effective configuration with other. This // Diff compares this view's captured effective configuration with other. This
// view is the earlier (left) value and other is the later (right) value. The // view is the earlier (left) value and other is the later (right) value. The
// comparison delegates to ConfigKit's frozen effective-value semantics, so // comparison delegates to ConfigKit's frozen effective-value semantics, so
// source or resolution history alone does not create differences. Either zero // source or resolution history alone does not create differences. It does not
// view returns ErrInvalidConfig and no records. Returned records can contain // reread external sources or compare referenced file contents, resolved
// ordinary application data and are not evidence of equivalent execution // credential contents, later execution preparation, or request-specific
// behavior; callers choose where and to whom to disclose them. // overrides. Either zero view returns ErrInvalidConfig and no records; other
// ConfigKit errors are returned unchanged. An empty diff is not evidence of
// equivalent engine behavior or execution. Records can contain ordinary
// application data, so callers choose where and to whom to disclose them.
func (v ConfigurationInspection) Diff(other ConfigurationInspection) ([]configkit.Difference, error) { func (v ConfigurationInspection) Diff(other ConfigurationInspection) ([]configkit.Difference, error) {
if v.source == nil || other.source == nil { if v.source == nil || other.source == nil {
return nil, ErrInvalidConfig return nil, ErrInvalidConfig

View File

@@ -181,6 +181,41 @@ shows backend-completed execution settings for one profile, and `Prepare` or
`PreparedExecution.Details` shows request-specific rendered messages, inputs, `PreparedExecution.Details` shows request-specific rendered messages, inputs,
and validation resources. None of those views is a substitute for the others. and validation resources. None of those views is a substitute for the others.
To review changes between two independently captured configurations, compare
their inspection views:
```go
earlier, err := earlierEngine.InspectConfiguration()
if err != nil {
return err
}
later, err := candidateEngine.InspectConfiguration()
if err != nil {
return err
}
differences, err := earlier.Diff(later)
if err != nil {
return err
}
for _, difference := range differences {
if difference.HiddenChanged {
// Report a protected change without inferring its value.
}
if difference.Left.Redacted || difference.Right.Redacted {
// Apply the application's disclosure policy before presenting snapshots.
}
}
```
See the [`ConfigurationInspection.Diff` GoDoc](../../configuration_inspection.go)
and ConfigKit's [v0.7.0 effective-configuration diff guidance](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.0/docs/config.md#effective-configuration-diffs)
for the exact comparison contract. The operation compares only frozen effective
configuration values: it does not reread external files or compare their
contents, resolved credential contents, later execution preparation, or
request-specific overrides. An empty diff is not proof of equivalent execution.
Records can contain ordinary application data, so use the application's
disclosure policy when presenting them.
## Inspect A Prompt Before Preparation ## Inspect A Prompt Before Preparation
Use [`Engine.InspectPrompt`](../../engine.go) to check one configured prompt's Use [`Engine.InspectPrompt`](../../engine.go) to check one configured prompt's

View File

@@ -21,6 +21,16 @@ profile inheritance. It retains ConfigKit's result privately for explicit
inspection, not for per-run resolution. The runtime/domain packages do not inspection, not for per-run resolution. The runtime/domain packages do not
depend on ConfigKit. depend on ConfigKit.
The `ConfigurationInspection.Diff` facade method compares two retained results
through a private wrapper and a narrow `internal/configuration.Diff` bridge.
The wrapper keeps `Result[document]` inside the adapter; the bridge delegates
once to ConfigKit v0.7.0 and returns its public difference records. Comparison
uses only frozen effective values and does not reopen sources, resolve runtime
credentials, or enter the execution path. ConfigKit applies sensitivity from
both results; reports may still contain ordinary application data. See the
[consumer comparison guide](../consumers/pkg-promptkit.md#inspect-the-captured-configuration)
and ConfigKit's [v0.7.0 comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.0/docs/config.md#effective-configuration-diffs).
After prompt materialization and effective-profile snapshot construction, the After prompt materialization and effective-profile snapshot construction, the
adapter captures lexically ordered, identity-only inventories from the final adapter captures lexically ordered, identity-only inventories from the final
prompt and indexed-profile maps. Its listing methods return caller-owned copies prompt and indexed-profile maps. Its listing methods return caller-owned copies
@@ -49,9 +59,9 @@ strings, including empty strings. It closes content-file handles before
returning and retains no source capability for public inspection. returning and retains no source capability for public inspection.
Role and cache-control normalization is applied to execution-owned message Role and cache-control normalization is applied to execution-owned message
copies. The retained ConfigKit configuration keeps effective input message copies. ConfigKit v0.7.0 retains effective input message metadata and its
metadata and its resource origins: recording a sequence-wide normalization in resource origins; recording a sequence-wide normalization in the retained
ConfigKit v0.6.0 would replace origins of unchanged content-file fields. configuration would replace origins of unchanged content-file fields.
The runner selects full definitions from this index for preparation and uses The runner selects full definitions from this index for preparation and uses
captured prompt metadata for `InspectPrompt` and `InspectRequirements`; the captured prompt metadata for `InspectPrompt` and `InspectRequirements`; the

View File

@@ -1,6 +1,8 @@
# Captured Configuration Comparison # Captured Configuration Comparison
Status: accepted; implementation pending. Status: Implemented (2026-10-09). PromptKit exposes captured configuration
comparison through `ConfigurationInspection.Diff`; see the
[implementation plan](implementation.md) for the completed work and verification.
## Purpose ## Purpose

View File

@@ -58,8 +58,9 @@ This wrapper is an implementation choice, not a new consumer contract.
**Status: Complete.** The selected tag resolves to reviewed commit **Status: Complete.** The selected tag resolves to reviewed commit
`8f3396d6f0cbe03af4f92bb2c1a1c9798171dd52`; upstream `COPYRIGHT` and `LICENSE` `8f3396d6f0cbe03af4f92bb2c1a1c9798171dd52`; upstream `COPYRIGHT` and `LICENSE`
are unchanged from v0.6.0. `GOTOOLCHAIN=local go test ./...`, are unchanged from v0.6.0. `GOTOOLCHAIN=local go test ./...`,
`GOTOOLCHAIN=local go vet ./...`, `GOTOOLCHAIN=local python3 `GOTOOLCHAIN=local go vet ./...`,
scripts/check-examples.py`, and `git diff --check` passed. `GOTOOLCHAIN=local python3 scripts/check-examples.py`, and
`git diff --check` passed.
Scope: dependency and attribution changes only. Scope: dependency and attribution changes only.
@@ -163,8 +164,8 @@ sequence, sensitivity, and ordering cases.
views repeatedly after both sources become unreadable, and concurrently runs views repeatedly after both sources become unreadable, and concurrently runs
inspection, comparison, and offline execution against those captured engines. inspection, comparison, and offline execution against those captured engines.
It confirms stable differences without source reads or comparison-triggered It confirms stable differences without source reads or comparison-triggered
model calls. `GOTOOLCHAIN=local go test -race . ./internal/configuration model calls. `GOTOOLCHAIN=local go test -race . ./internal/configuration ./internal/engine`
./internal/engine` and `git diff --check` passed. and `git diff --check` passed.
Scope: lifecycle and concurrency integration tests. Scope: lifecycle and concurrency integration tests.
@@ -189,6 +190,14 @@ concurrent read-only use without involving prompt execution machinery.
## Stage 5: Document The Feature And Validate The Integrated Change ## Stage 5: Document The Feature And Validate The Integrated Change
**Status: Complete.** Added the consumer example, comparison GoDoc, and internal
bridge documentation; updated the feature roadmap to implemented. v0.13.0 is
already published, so its note remains unchanged; include this feature in the
next release note. `GOTOOLCHAIN=local go test -race ./...`,
`GOTOOLCHAIN=local go vet ./...`,
`GOTOOLCHAIN=local python3 scripts/check-examples.py`, affected local and
ConfigKit v0.7.0 link-target checks, and `git diff --check` passed.
Scope: canonical documentation and final verification. Scope: canonical documentation and final verification.
1. Add a small comparison example to the configuration-inspection section of 1. Add a small comparison example to the configuration-inspection section of