diff --git a/configuration_inspection.go b/configuration_inspection.go index a17830b..bbde744 100644 --- a/configuration_inspection.go +++ b/configuration_inspection.go @@ -30,10 +30,13 @@ func (e *Engine) InspectConfiguration() (ConfigurationInspection, error) { // 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 // comparison delegates to ConfigKit's frozen effective-value semantics, so -// source or resolution history alone does not create differences. Either zero -// view returns ErrInvalidConfig and no records. Returned records can contain -// ordinary application data and are not evidence of equivalent execution -// behavior; callers choose where and to whom to disclose them. +// source or resolution history alone does not create differences. It does not +// reread external sources or compare referenced file contents, resolved +// credential contents, later execution preparation, or request-specific +// 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) { if v.source == nil || other.source == nil { return nil, ErrInvalidConfig diff --git a/docs/consumers/pkg-promptkit.md b/docs/consumers/pkg-promptkit.md index b10fbd7..50fa1bd 100644 --- a/docs/consumers/pkg-promptkit.md +++ b/docs/consumers/pkg-promptkit.md @@ -181,6 +181,41 @@ shows backend-completed execution settings for one profile, and `Prepare` or `PreparedExecution.Details` shows request-specific rendered messages, inputs, 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 Use [`Engine.InspectPrompt`](../../engine.go) to check one configured prompt's diff --git a/docs/internal/sources.md b/docs/internal/sources.md index d270be8..fe60043 100644 --- a/docs/internal/sources.md +++ b/docs/internal/sources.md @@ -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 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 adapter captures lexically ordered, identity-only inventories from the final 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. Role and cache-control normalization is applied to execution-owned message -copies. The retained ConfigKit configuration keeps effective input message -metadata and its resource origins: recording a sequence-wide normalization in -ConfigKit v0.6.0 would replace origins of unchanged content-file fields. +copies. ConfigKit v0.7.0 retains effective input message metadata and its +resource origins; recording a sequence-wide normalization in the retained +configuration would replace origins of unchanged content-file fields. The runner selects full definitions from this index for preparation and uses captured prompt metadata for `InspectPrompt` and `InspectRequirements`; the diff --git a/docs/roadmap/diff.md b/docs/roadmap/diff.md index 64d07c4..d5abf82 100644 --- a/docs/roadmap/diff.md +++ b/docs/roadmap/diff.md @@ -1,6 +1,8 @@ # 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 diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 36fef47..3a3c9f7 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -58,8 +58,9 @@ This wrapper is an implementation choice, not a new consumer contract. **Status: Complete.** The selected tag resolves to reviewed commit `8f3396d6f0cbe03af4f92bb2c1a1c9798171dd52`; upstream `COPYRIGHT` and `LICENSE` are unchanged from v0.6.0. `GOTOOLCHAIN=local go test ./...`, -`GOTOOLCHAIN=local go vet ./...`, `GOTOOLCHAIN=local python3 -scripts/check-examples.py`, and `git diff --check` passed. +`GOTOOLCHAIN=local go vet ./...`, +`GOTOOLCHAIN=local python3 scripts/check-examples.py`, and +`git diff --check` passed. 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 inspection, comparison, and offline execution against those captured engines. It confirms stable differences without source reads or comparison-triggered -model calls. `GOTOOLCHAIN=local go test -race . ./internal/configuration -./internal/engine` and `git diff --check` passed. +model calls. `GOTOOLCHAIN=local go test -race . ./internal/configuration ./internal/engine` +and `git diff --check` passed. 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 +**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. 1. Add a small comparison example to the configuration-inspection section of