From d14fa366f51d3ac2598f1263b6e18ff4232429be Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 7 Nov 2026 05:06:47 +0000 Subject: [PATCH] Align reporting contracts and documentation --- README.md | 9 ++-- docs/cli.md | 18 ++++---- docs/consumers/guide.md | 66 ++++++++------------------- docs/development.md | 49 ++++++++++---------- docs/internal/overview.md | 7 +-- docs/policy/architecture.md | 8 ++-- docs/policy/testing.md | 3 ++ docs/roadmap/implementation.md | 8 +++- docs/roadmap/promptkit-v0.20.0.md | 5 +- integrations/ckconfig/README.md | 2 +- integrations/ckconfig/contracts.go | 4 +- integrations/ckconfig/explain.go | 46 +++++++++---------- integrations/ckconfig/sources.go | 54 +++++++++++----------- integrations/ckconfig/sources_test.go | 27 ++++++----- integrations/ckprompt/README.md | 11 +++-- integrations/ckprompt/doc.go | 10 ++-- integrations/ckprompt/go.sum | 2 - 17 files changed, 160 insertions(+), 169 deletions(-) diff --git a/README.md b/README.md index 2a0c1b4..647a803 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ The core captures reusable command declarations, validates installation batches before changing an application's registry, converts typed inputs before constructing them, and returns outcomes without exiting the process. Its [consumer guide](docs/consumers/guide.md) covers declaration, invocation -reporting, and migration. Each handler receives one invocation reporter for +and reporting. Each handler receives one invocation reporter for substantive output, categorized messages, and terminal explanations; `Execute` returns delivery observations with the outcome. The [CLI reference](docs/cli.md) defines the shared visibility policy. @@ -25,9 +25,10 @@ defines the shared visibility policy. Importing an integration does not install commands. The published ckconfig and ckprompt v0.2.0 modules use core v0.3.0. The published ckconfig v0.3.0 uses ConfigKit v1.1.0 and does not compose with -ckprompt v0.2.0; the published v0.2.0 pair remains matched. Current ckprompt -source aligns with ckconfig v0.3.0; its v0.3.0 candidate is not yet published. See the -[consumer guide](docs/consumers/guide.md#module-selection) for migration details. +ckprompt v0.2.0; the published v0.2.0 pair remains matched. Current integration +sources use new core and ckconfig APIs and are developed in an aligned workspace +until their release dependencies are available. See the +[consumer guide](docs/consumers/guide.md#module-selection) for dependency details. ## Examples diff --git a/docs/cli.md b/docs/cli.md index 4412157..7fe58f1 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -114,7 +114,7 @@ and usage guidance go to `Streams.Err`. The shared `--format` flag selects `text`, `yaml`, or `json` for reports submitted through the core reporter. When omitted, a report's text template selects text; otherwise scalar values and nonempty string lists use text, while -structured values and empty collections use YAML. Explicit text without a +structured values, empty collections, and null use YAML. Explicit text without a template uses YAML for structured values. Invalid or empty format values are usage errors. Raw output, help, completion, and diagnostics are not encoded as reports. @@ -537,7 +537,7 @@ separate evidence and does not replace a nonzero difference outcome. For ConfigKit-backed scopes, ConfigKit compares frozen effective typed values after defaults and resolution; source or provenance differences alone do not create a change. PromptKit delegates its native comparison to ConfigKit. The -report contains `additions`, `changes`, and `deletions`. Additions and changes +concise report contains `additions`, `changes`, and `deletions`. Additions and changes preserve semantic paths and contain right-side values provided by the native comparison. Deletions contain canonical JSON Pointer paths. Explicit null is a value; it is not a deletion. Changed sequences @@ -545,7 +545,7 @@ 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. For those ConfigKit-backed -comparisons, the report omits separate redaction and hidden-change metadata: a +comparisons, the concise 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 strings. An empty comparison succeeds with this shape: @@ -561,7 +561,7 @@ 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 empty results. +Without `--check`, successful comparisons return status `0`, including 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. @@ -804,7 +804,7 @@ configuration and credential checks. It does not make a model call or retain a prepared execution snapshot. A successful report describes this preparation invocation; it does not certify provider acceptance or guarantee later execution. See PromptKit's -[`Engine.ValidateRequest` API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/engine.go). +[`Engine.ValidateRequest` API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/engine.go). Builder, engine-loading, and native validation errors use the operational path (status `1`) with supported error identity and acquired diagnostics retained. @@ -867,7 +867,7 @@ identities. YAML examples follow: A catalog result is an inventory, not a readiness check or execution result. The owning provider controls membership and order. Namespace filters are passed to PromptKit without local membership interpretation. See the -[PromptKit v0.18.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/docs/consumers/pkg-promptkit.md) +[PromptKit v0.20.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/consumers/pkg-promptkit.md) for native resource and selection definitions. ### PromptKit smoke testing @@ -1016,9 +1016,9 @@ operation causes. Syntax, operand, unsupported format, and conflicting namespace selection are usage status `2`. Native configuration, selection, and diagnostic meanings remain owned by -PromptKit. See the [v0.18.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/docs/consumers/pkg-promptkit.md), -[smoke API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/smoke_diagnostics.go), -and [engine API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/engine.go). +PromptKit. See the [v0.20.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/consumers/pkg-promptkit.md), +[smoke API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/smoke_diagnostics.go), +and [engine API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/engine.go). ## Outcome status diff --git a/docs/consumers/guide.md b/docs/consumers/guide.md index 4cfee1b..ef0c464 100644 --- a/docs/consumers/guide.md +++ b/docs/consumers/guide.md @@ -18,17 +18,17 @@ installed at the application root, not as group children. The published matched releases are core v0.3.0, ckconfig v0.2.0, and ckprompt v0.2.0. The published ckconfig v0.3.0 uses ConfigKit v1.1.0 and does not compose with ckprompt v0.2.0, which retains ckconfig v0.2.0 and ConfigKit v0.8.0. -Update application imports and dependency versions together; old and new core -paths have distinct Go type identities. Install core with +Install core with `go get go.maximumdirect.net/commandkit@v0.3.0` and either integration with `go get go.maximumdirect.net/ckconfig@v0.2.0` or `go get go.maximumdirect.net/ckprompt@v0.2.0`. The current ckprompt source targets ckconfig v0.3.0, ConfigKit v1.1.0, and -PromptKit v0.18.0 using their `go.maximumdirect.net` identities. Its v0.3.0 +PromptKit v0.20.0 using their `go.maximumdirect.net` identities. Its v0.3.0 release is a candidate, not a published release. A Go 1.27.0 workspace may -compose all three local modules; independent tests with `GOWORK=off` exercise -the declared releases. +compose all three local modules. The current integration source uses APIs that +require the upcoming core and ckconfig releases; independent validation follows +their publication and dependency alignment. The two integrations are independent optional imports. `ckprompt` uses the public scope and error contracts from `ckconfig`; importing it does not add the @@ -142,6 +142,13 @@ use `Output()` or `RenderOutput()` for deliberate raw output. Use `Warn`, `Info` [CLI reference](../cli.md#reporting) owns flag grammar, visibility, prefixes, and status behavior. +Reports use JSON serialization to establish the common value representation +for YAML and JSON. A text template receives the original value; without one, +text uses readable scalar or string-list output and YAML for structured values. +The CLI's shared format selection and the writer-level `RenderReport` use the +same rules. Use `DecodeYAMLReport` only for safe upstream inspection YAML that +must become a report value; ordinary strings are not parsed as YAML. + Return terminal text with `Failure(message, details...)`, `Usage(message, details...)`, or `WithExplanation` on a domain outcome. Attach an optional Go error separately with `WithCause`. A cause is preserved for inspection, but it @@ -167,15 +174,6 @@ invocation are safe concurrently, but concurrent submission order is not specified. The caller owns the writers passed to `Execute`; CommandKit does not close them. -### Migrating from the previous reporting API - -| Previous API | Current API | -| --- | --- | -| `invocation.Streams.Out` / `.Err` | `invocation.Reporter().Output()` and categorized reporter methods. `Streams` remains the argument to `App.Execute`. | -| `Failure(err)` / `Usage(err)` | `Failure("operator-facing explanation").WithCause(err)` / `Usage("usage explanation").WithCause(err)`. Choose the explanation deliberately; the cause alone is not printed. | -| `Outcome.Diagnostics` or terminal `SeverityError` | Submit independent messages through reporter methods. Put failure context in `Explanation`; provider `Acquired.Diagnostics` remains passive data for the owning integration to submit. | -| `ReportIncomplete`, `DiagnosticDelivery`, or `DeliveryError` | Inspect `Outcome.Presentation.Output` and `.Diagnostics`, including each `DeliveryResult.State`, `RenderError`, and `WriteError`. | - ## Application-owned aliases Pass commands and aliases together as declarations. Integration factories can @@ -266,6 +264,8 @@ parses CLI records but cannot add them to an already-loaded result. The engine's captured configuration. Add that scope to a `ckconfig.Suite` to expose it under `config` with validate/show/sources/explain and native diff operations; it does not install PromptKit catalog, definition, or requirements commands. +Its override feature is disabled because the released PromptKit configuration +loader does not accept ConfigKit override records. `ckprompt.FromEngine(loadEngine)` supplies nine callbacks: prompt, profile, backend, namespace, and collection catalogs; named prompt, profile, and backend @@ -396,19 +396,7 @@ These are independent defaults for unqualified caller-supplied prompt, profile, and backend names; qualified IDs pass through. Stored references and configuration inspection are unchanged, while namespace and collection inventories remain global. Catalog `--namespace` filters are separate from these defaults. See the released -[namespace API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/namespaces.go). - -### PromptKit configuration migration - -The current integration uses identified resource lists and keeps PromptKit's -native default OpenRouter bundle. Loaders can opt out with -`promptkit.WithBundledOpenRouter(false)`. Catalogs and configuration reports -expose the supplied engine's inventory and native source evidence. The -[upstream migration guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/docs/consumers/configuration-migration.md) -covers list records, inheritance, source-root controls, and import requiredness. -Prompt catalog, prompt and requirements inspection, and smoke target reports no -longer carry descriptive prompt versions; collection release labels and source -version evidence retain their own meanings. +[namespace API](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/namespaces.go). ## Outcomes and ownership @@ -423,23 +411,7 @@ Go declarations and GoDoc own exact exported contracts. ConfigKit owns configuration decoding, validation, and provenance. PromptKit owns prompt formats, profile resolution, and inspection details. See the [ConfigKit v1.1.0 source records](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/records.go), -[PromptKit engine methods](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/engine.go), -[configuration inspection](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/configuration_inspection.go), -[smoke diagnostics](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/smoke_diagnostics.go), -and [PromptKit v0.18.0 consumer guidance](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/docs/consumers/pkg-promptkit.md). - -## ConfigKit v1.1 migration - -Ckconfig v0.3.0 uses `go.maximumdirect.net/configkit v1.1.0` -and Go 1.27.0. Consumers must migrate ConfigKit imports and values passed to -ckconfig: the old and new package paths have distinct type identities. Source -reports rename `destination_unresolved` to `destination_is_fallback` and -`version_check` to `version_evidence`, and add `empty_import_selections`. - -The upstream [v0.9 migration notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v0.9.0.md), -[v0.10 notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v0.10.0.md), -[v1.0 migration notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v1.0.0.md), -and [v1.1 notes](https://forge.maximumdirect.net/base-layer/configkit/src/commit/191015e289d7f2b91abb9fdd9c4f2f5cf75b4de9/docs/releases/v1.1.0.md) -cover source-root `configkit` controls becoming `config`, import requiredness -and defaults, collection registration and operations, removed APIs, and CLI -assignment order. +[PromptKit engine methods](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/engine.go), +[configuration inspection](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/configuration_inspection.go), +[smoke diagnostics](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/smoke_diagnostics.go), +and [PromptKit v0.20.0 consumer guidance](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/consumers/pkg-promptkit.md). diff --git a/docs/development.md b/docs/development.md index b79f43f..475bddf 100644 --- a/docs/development.md +++ b/docs/development.md @@ -103,8 +103,8 @@ under their canonical owners. The root module does not traverse nested modules. Preserve the ignored `go.work` and `go.work.sum`; use `GOWORK=off GOTOOLCHAIN=local` for dependency preparation -and independent module suites. With a Go 1.27.0 workspace containing all three modules, normal -workspace discovery also validates local composition. +and independent module suites once released requirements are aligned. Until then, +the integrations require a Go 1.27.0 workspace containing all three modules. Run `GOWORK=off GOTOOLCHAIN=local go test ./...` separately from each module directory. From the repository root, a workspace containing all three modules can also run: @@ -133,30 +133,31 @@ or publishing. ## Current public examples -The maintained consumers compile with their owning module suites and run without -external services. The PromptKit smoke examples use local fixtures and the -example's configured client: +The maintained consumers run without external services using the aligned local +workspace. The PromptKit smoke examples use local fixtures and the example's +configured client: ```sh -GOWORK=off GOTOOLCHAIN=local go run ./examples/core workspace greet --count=0 --tag=first --tag second -(cd integrations/ckconfig/examples/simple && GOWORK=off GOTOOLCHAIN=local go run . config show) -(cd integrations/ckconfig/examples/simple && GOWORK=off GOTOOLCHAIN=local go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . config validate --scope all --campaign spring --limit=0) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . config diff --scope promptkit --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit list prompts --config fixtures/before.yml --campaign spring) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit list profiles --config fixtures/after.yml --campaign autumn --format yaml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit list backends --namespace team) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit list namespaces --kind prompt --kind profile) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit list collections) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit show prompt briefing --campaign spring --format yaml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit requirements show briefing --campaign spring) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit requirements validate briefing --campaign spring --input topic=fixtures/topic.txt) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit requirements validate briefing --campaign spring --input topic=fixtures/topic.txt --var mode=full --input notes=fixtures/notes.txt --format yaml) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit test reachability --campaign spring --prompt briefing --profile spring) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . promptkit test all --campaign spring --prompt briefing --profile spring) -(cd integrations/ckprompt/examples/composed && GOWORK=off GOTOOLCHAIN=local go run . session restore session-42 --campaign spring) +GOTOOLCHAIN=local go run ./examples/core workspace greet --count=0 --tag=first --tag second +(cd integrations/ckconfig/examples/simple && GOTOOLCHAIN=local go run . config show) +(cd integrations/ckconfig/examples/simple && GOTOOLCHAIN=local go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . config validate --scope all --campaign spring --limit=0) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . config diff --scope promptkit --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit list prompts --config fixtures/before.yml --campaign spring) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit list profiles --config fixtures/after.yml --campaign autumn --format yaml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit list backends --namespace team) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit list namespaces --kind prompt --kind profile) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit list collections) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit show prompt briefing --campaign spring --format yaml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}') +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit requirements show briefing --campaign spring) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit requirements validate briefing --campaign spring --input-file topic=fixtures/topic.txt) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit requirements validate briefing --campaign spring --input-file topic=fixtures/topic.txt --var mode=full --input-file notes=fixtures/notes.txt --format yaml) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit test reachability --campaign spring --prompt briefing --profile spring) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . promptkit test all --campaign spring --prompt briefing --profile spring) +(cd integrations/ckprompt/examples/composed && GOTOOLCHAIN=local go run . session restore session-42 --campaign spring) ``` The [consumer guide](consumers/guide.md) explains how their public API usage diff --git a/docs/internal/overview.md b/docs/internal/overview.md index 975ee8b..9565735 100644 --- a/docs/internal/overview.md +++ b/docs/internal/overview.md @@ -14,7 +14,7 @@ The core, ckconfig, and ckprompt modules declare The root facade owns captured canonical command declarations, application-owned routing rules, binding conversion, invocation coordination, the per-App -registries, standard help/version commands, invocation reporting, and outcome +registries, standard help/version commands, shared report rendering, invocation reporting, and outcome finalization. Its dependency graph has no ConfigKit or PromptKit integration dependency. Applications provide typed callbacks and install routing rules alongside the @@ -90,8 +90,9 @@ acquisitions or comparison callback. `integrations/ckprompt` owns PromptKit engine loading, configuration-scope adaptation and native comparison, plus optional prompt/profile/backend/namespace/ collection catalogs, named inspection, native requirements discovery, -concrete request validation, and native smoke testing. Validation and smoke -testing delegate to PromptKit and are independently opted into a suite. Smoke +concrete request validation, prepared-request preview, and native smoke testing. +Validation, preview, and smoke testing delegate to PromptKit and are independently +opted into a suite. Smoke operations use the application's native engine and its configured client or probes. The integration uses public core and ckconfig contracts plus PromptKit's public APIs. It does not add a configuration family when its declaration is diff --git a/docs/policy/architecture.md b/docs/policy/architecture.md index 66eea72..e92a1a7 100644 --- a/docs/policy/architecture.md +++ b/docs/policy/architecture.md @@ -213,8 +213,8 @@ 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 +separately with its scope identity and selection, applying only the selectors +supplied for that side. Finish both checks before initializing shared state once and invoking the integration-owned pair provider. The [consumer guide](../consumers/guide.md#configkit-scopes) and linked GoDoc own the provider lifecycle; the [CLI reference](../cli.md#compare-configuration-selections) @@ -346,8 +346,8 @@ errors instead of inventing a parallel override policy or retrying with altered values. Application loading and application-owned overrides retain their own responsibilities. -The [CLI reference](../cli.md#show-effective-configuration) owns current native -report formats and operation-specific preparation and delivery timing. Semantic +The [CLI reference](../cli.md#show-effective-configuration) owns current report +formats and operation-specific preparation and delivery timing. Semantic comparison exposes the adopted upstream comparison API and carries its evidence through the provider boundary; it does not introduce a CommandKit equality engine. diff --git a/docs/policy/testing.md b/docs/policy/testing.md index 869c8ab..25db4b1 100644 --- a/docs/policy/testing.md +++ b/docs/policy/testing.md @@ -73,6 +73,9 @@ integration where correctness depends on that interaction. Internal package tests own focused mechanisms. Boundary checks protect selected architectural constraints; behavioral evidence protects invocation semantics and ownership through conversions. +For shared reports, compare logical values and selected evidence rather than +YAML formatting or mapping order. Preserve sequence ordering only where the +relevant contract gives it meaning. Do not infer concurrent-dispatch support from fresh invocation state. Test concurrency guarantees only if deliberately selected. Coverage targets, race diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 145235a..7e24587 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Shared reporting and PromptKit v0.20.0 implementation plan -Status: implementation in progress; Stages 1–22 complete. +Status: implementation in progress; Stages 1–23 complete. ## Scope, authority, and execution @@ -831,6 +831,12 @@ do not reimplement native resolution tests. ## Stage 23: Canonical contracts and obsolete infrastructure audit +**Complete.** Audited the output inventory and public boundaries, removed +unused YAML report tags, aligned current documentation and policy wording, and +tidied integration dependencies. The workspace suites and 20 development example +commands passed with Go 1.27.0; independent integration validation awaits the +released dependencies. + Review every path in the feature roadmap's [output inventory](promptkit-v0.20.0.md#output-implementation-inventory). Remove remaining handler-local format inputs, validators, encoders, legacy diff --git a/docs/roadmap/promptkit-v0.20.0.md b/docs/roadmap/promptkit-v0.20.0.md index ed5818f..7f0f70c 100644 --- a/docs/roadmap/promptkit-v0.20.0.md +++ b/docs/roadmap/promptkit-v0.20.0.md @@ -1,6 +1,6 @@ # Shared report output, PromptKit v0.20.0 adoption, and ConfigKit operator CLI -Status: agreed feature roadmap; implementation has not started. The numbered +Status: agreed feature roadmap; implementation is in progress. The numbered decisions and final review clarifications are settled. The [implementation plan](implementation.md) owns staged execution and concrete API and transition choices; native resource report fields follow upstream. Practical @@ -673,7 +673,8 @@ the plan; the checklist here defines the target acceptance boundaries. Select focused boundary tests under the [testing policy](../policy/testing.md). The ownership and Go-native policy work is complete in [architecture.md](../policy/architecture.md#ownership-boundaries). The checks below -cover implementation and its documentation, which remain pending. +cover implementation and its documentation across the staged work; final +release-dependent checks remain pending. The checklist concerns core reporting and adapter/CLI behavior; it does not ask CommandKit to retest PromptKit rendering, schema, namespace, or ConfigKit resolution algorithms. diff --git a/integrations/ckconfig/README.md b/integrations/ckconfig/README.md index 01b27fa..e634694 100644 --- a/integrations/ckconfig/README.md +++ b/integrations/ckconfig/README.md @@ -28,7 +28,7 @@ ConfigKit loader. The `config` command family exposes scope discovery and the validate, show, sources, explain, and diff operations supported by the declared scopes. Source reports include native destination, placement, destination fallback, version evidence, and empty-import selections. Comparison returns -ConfigKit's native records to the YAML report path; the +ConfigKit's native records to shared report rendering; the [CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections) owns its operator details. diff --git a/integrations/ckconfig/contracts.go b/integrations/ckconfig/contracts.go index 57cb9c3..4e615f1 100644 --- a/integrations/ckconfig/contracts.go +++ b/integrations/ckconfig/contracts.go @@ -47,7 +47,7 @@ type Request struct { // initialized and checked typed input. The supplied-state fields of Selection // are preserved for the scope's loader. type ComparisonSide[I any] struct { - // Selection carries the explicit config and overlay inputs for this side. + // Selection carries the explicit config, overlay, and override inputs for this side. Selection Selection // Input is initialized and checked for this side before comparison. Input I @@ -118,7 +118,7 @@ type ScopeFeatures struct { type Scope[I, S any] struct { // Name identifies the scope in CLI selection and reports. Name string - // Summary describes the scope. Scope discovery reports name and operations only. + // Summary describes the scope. Summary string // Operations selects the standard handlers exposed for this scope. Operations []Operation diff --git a/integrations/ckconfig/explain.go b/integrations/ckconfig/explain.go index 84125d9..a452e22 100644 --- a/integrations/ckconfig/explain.go +++ b/integrations/ckconfig/explain.go @@ -11,12 +11,12 @@ import ( ) type explanationReport struct { - Scope string `json:"scope" yaml:"scope"` - Path string `json:"path" yaml:"path"` - Effective snapshotDTO `json:"effective" yaml:"effective"` - Origin explanationOriginDTO `json:"origin" yaml:"origin"` - History []explanationChangeDTO `json:"history" yaml:"history"` - SecretReference *secretReferenceDTO `json:"secret_reference" yaml:"secret_reference"` + Scope string `json:"scope"` + Path string `json:"path"` + Effective snapshotDTO `json:"effective"` + Origin explanationOriginDTO `json:"origin"` + History []explanationChangeDTO `json:"history"` + SecretReference *secretReferenceDTO `json:"secret_reference"` Metadata *explanationMetadata `json:"metadata,omitempty"` } @@ -49,35 +49,35 @@ type pathMetadata struct { var pathDiscoveryTemplate = template.Must(commandkit.ParseTextTemplate("paths", "{{range .Paths}}{{printf \"%q\" .Path}} {{if .Present}}{{if .Metadata.Explicit}}explicit{{else}}non-explicit{{end}}{{else}}historical{{end}}\n{{end}}", nil)) type snapshotDTO struct { - Present bool `json:"present" yaml:"present"` - Redacted bool `json:"redacted" yaml:"redacted"` - YAML string `json:"yaml" yaml:"yaml"` + Present bool `json:"present"` + Redacted bool `json:"redacted"` + YAML string `json:"yaml"` } type explanationOriginDTO struct { - Layer string `json:"layer" yaml:"layer"` - Locations []locationDTO `json:"locations" yaml:"locations"` - Operation string `json:"operation" yaml:"operation"` - Inheritance []inheritanceStepDTO `json:"inheritance" yaml:"inheritance"` + Layer string `json:"layer"` + Locations []locationDTO `json:"locations"` + Operation string `json:"operation"` + Inheritance []inheritanceStepDTO `json:"inheritance"` } type inheritanceStepDTO struct { - From string `json:"from" yaml:"from"` - To string `json:"to" yaml:"to"` - Reference string `json:"reference" yaml:"reference"` - Locations []locationDTO `json:"locations" yaml:"locations"` + From string `json:"from"` + To string `json:"to"` + Reference string `json:"reference"` + Locations []locationDTO `json:"locations"` } type explanationChangeDTO struct { - Before snapshotDTO `json:"before" yaml:"before"` - After snapshotDTO `json:"after" yaml:"after"` - Origin explanationOriginDTO `json:"origin" yaml:"origin"` - Reasons []string `json:"reasons" yaml:"reasons"` - Dependencies []string `json:"dependencies" yaml:"dependencies"` + Before snapshotDTO `json:"before"` + After snapshotDTO `json:"after"` + Origin explanationOriginDTO `json:"origin"` + Reasons []string `json:"reasons"` + Dependencies []string `json:"dependencies"` } type secretReferenceDTO struct { - Name string `json:"name" yaml:"name"` + Name string `json:"name"` } func runConfigExplanation[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome { diff --git a/integrations/ckconfig/sources.go b/integrations/ckconfig/sources.go index bcc4a08..db45eb4 100644 --- a/integrations/ckconfig/sources.go +++ b/integrations/ckconfig/sources.go @@ -10,48 +10,48 @@ import ( ) type sourceReport struct { - Scope string `json:"scope" yaml:"scope"` - Sources []sourceDTO `json:"sources" yaml:"sources"` + Scope string `json:"scope"` + Sources []sourceDTO `json:"sources"` } type sourceDTO struct { - ID string `json:"id" yaml:"id"` - Label string `json:"label" yaml:"label"` - Path string `json:"path" yaml:"path"` - Destination string `json:"destination" yaml:"destination"` - Placement string `json:"placement" yaml:"placement"` - DestinationIsFallback bool `json:"destination_is_fallback" yaml:"destination_is_fallback"` - Layer string `json:"layer" yaml:"layer"` - Kind string `json:"kind" yaml:"kind"` - UnderlayIndex int `json:"underlay_index" yaml:"underlay_index"` - ImportedFrom *locationDTO `json:"imported_from" yaml:"imported_from"` - VersionEvidence *sourceVersionEvidenceDTO `json:"version_evidence" yaml:"version_evidence"` - EmptyImportSelections []emptyImportSelectionDTO `json:"empty_import_selections" yaml:"empty_import_selections"` + ID string `json:"id"` + Label string `json:"label"` + Path string `json:"path"` + Destination string `json:"destination"` + Placement string `json:"placement"` + DestinationIsFallback bool `json:"destination_is_fallback"` + Layer string `json:"layer"` + Kind string `json:"kind"` + UnderlayIndex int `json:"underlay_index"` + ImportedFrom *locationDTO `json:"imported_from"` + VersionEvidence *sourceVersionEvidenceDTO `json:"version_evidence"` + EmptyImportSelections []emptyImportSelectionDTO `json:"empty_import_selections"` } type emptyImportSelectionDTO struct { - Path string `json:"path" yaml:"path"` - Location locationDTO `json:"location" yaml:"location"` - Selector string `json:"selector" yaml:"selector"` + Path string `json:"path"` + Location locationDTO `json:"location"` + Selector string `json:"selector"` } type locationDTO struct { - SourceID string `json:"source_id" yaml:"source_id"` - Line int `json:"line" yaml:"line"` - Column int `json:"column" yaml:"column"` + SourceID string `json:"source_id"` + Line int `json:"line"` + Column int `json:"column"` } type sourceVersionEvidenceDTO struct { - Path string `json:"path" yaml:"path"` - Version versionDTO `json:"version" yaml:"version"` - Location *locationDTO `json:"location" yaml:"location"` - Redacted bool `json:"redacted" yaml:"redacted"` + Path string `json:"path"` + Version versionDTO `json:"version"` + Location *locationDTO `json:"location"` + Redacted bool `json:"redacted"` } type versionDTO struct { - Present bool `json:"present" yaml:"present"` - Null bool `json:"null" yaml:"null"` - Text string `json:"text" yaml:"text"` + Present bool `json:"present"` + Null bool `json:"null"` + Text string `json:"text"` } func runConfigSources[I, S any](invocation commandkit.Invocation, plan *configOperationPlan[I, S], state S) commandkit.Outcome { diff --git a/integrations/ckconfig/sources_test.go b/integrations/ckconfig/sources_test.go index f13f40d..05a8f8e 100644 --- a/integrations/ckconfig/sources_test.go +++ b/integrations/ckconfig/sources_test.go @@ -74,12 +74,20 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) { var report struct { Scope string `yaml:"scope"` Sources []struct { - ID string `yaml:"id"` - Destination string `yaml:"destination"` - Placement string `yaml:"placement"` - Layer string `yaml:"layer"` - EmptyImportSelections []emptyImportSelectionDTO `yaml:"empty_import_selections"` - DestinationIsFallback bool `yaml:"destination_is_fallback"` + ID string `yaml:"id"` + Destination string `yaml:"destination"` + Placement string `yaml:"placement"` + Layer string `yaml:"layer"` + EmptyImportSelections []struct { + Path string `yaml:"path"` + Location struct { + SourceID string `yaml:"source_id"` + Line int `yaml:"line"` + Column int `yaml:"column"` + } `yaml:"location"` + Selector string `yaml:"selector"` + } `yaml:"empty_import_selections"` + DestinationIsFallback bool `yaml:"destination_is_fallback"` VersionEvidence *struct { Path string `yaml:"path"` Version struct { @@ -108,11 +116,8 @@ func TestSourcesProjectNativeEvidenceInTextAndYAML(t *testing.T) { if root := report.Sources[0]; root.Destination != "" || root.Placement != "mapping" || root.DestinationIsFallback || root.VersionEvidence != nil || root.Layer != "main" { t.Errorf("root source projection = %#v", root) } - wantSelections := []emptyImportSelectionDTO{ - {Path: "/imports/first", Location: locationDTO{SourceID: "root.yml", Line: 3, Column: 4}, Selector: "glob"}, - {Path: "/imports/second", Location: locationDTO{}, Selector: "path"}, - } - if !reflect.DeepEqual(report.Sources[0].EmptyImportSelections, wantSelections) || report.Sources[1].EmptyImportSelections == nil || len(report.Sources[1].EmptyImportSelections) != 0 { + selections := report.Sources[0].EmptyImportSelections + if len(selections) != 2 || selections[0].Path != "/imports/first" || selections[0].Location.SourceID != "root.yml" || selections[0].Location.Line != 3 || selections[0].Location.Column != 4 || selections[0].Selector != "glob" || selections[1].Path != "/imports/second" || selections[1].Selector != "path" || report.Sources[1].EmptyImportSelections == nil || len(report.Sources[1].EmptyImportSelections) != 0 { t.Fatalf("import selections: %#v", report.Sources) } if strings.Contains(yamlOutput.String(), "destination_unresolved:") || strings.Contains(yamlOutput.String(), "version_check:") { diff --git a/integrations/ckprompt/README.md b/integrations/ckprompt/README.md index 0da74ec..bb1c191 100644 --- a/integrations/ckprompt/README.md +++ b/integrations/ckprompt/README.md @@ -9,9 +9,11 @@ Importing it does not install either command family. The module path is `go.maximumdirect.net/ckprompt`. This source uses Go 1.27.0, `go.maximumdirect.net/commandkit v0.3.0`, `go.maximumdirect.net/ckconfig v0.3.0`, -`go.maximumdirect.net/configkit v1.1.0`, and `go.maximumdirect.net/promptkit v0.18.0`. See the -[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-and-definitions) +`go.maximumdirect.net/configkit v1.1.0`, and `go.maximumdirect.net/promptkit v0.20.0`. See the +[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements) for callback, input, state, and acquisition contracts. +The current source requires the aligned local workspace until new core and +ckconfig releases supply its APIs. ## Example @@ -22,8 +24,9 @@ and native comparison in the `config` family. Install named inspections, and requirements discovery. `FromEngine` supplies nine PromptKit-backed callbacks: four inspections and five catalogs. Applications may narrow, wrap, or replace them before capture or provide custom callbacks -with `ckprompt.Suite`. Add concrete request validation and smoke testing -explicitly with `WithRequestValidation` and `WithSmokeTesting`. Inspection, +with `ckprompt.Suite`. Add concrete request validation, prepared-request preview, +and smoke testing explicitly with `WithRequestValidation`, +`WithRequestPreparation`, and `WithSmokeTesting`. Inspection, requirements, and catalog operations do not execute prompts or contact model providers; application loaders and callbacks retain their own effects. Smoke testing invokes the selected native PromptKit operation; the diff --git a/integrations/ckprompt/doc.go b/integrations/ckprompt/doc.go index 3a6c242..b0c10ec 100644 --- a/integrations/ckprompt/doc.go +++ b/integrations/ckprompt/doc.go @@ -1,13 +1,13 @@ // Package ckprompt, provided by go.maximumdirect.net/ckprompt, provides optional // PromptKit configuration comparison, // prompt catalogs, named inspections, requirements discovery and validation, -// and native smoke testing for CommandKit. Its command factories return -// canonical commandkit.Command declarations. Applications can install -// commandkit.RoutingRule aliases alongside them through commandkit.New or -// App.Register. Importing ckprompt installs neither family; callers compose its +// prepared-request preview, and native smoke testing for CommandKit. Command +// returns a canonical declaration; Declarations adds scoped flag aliases. +// Applications can install those alongside other declarations through +// commandkit.New or App.Register. Importing ckprompt installs neither family; callers compose its // declarations with core and ckconfig explicitly. Provider diagnostics remain // passive until the owning command submits them through the invocation // reporter, separately from any terminal explanation. This module uses -// PromptKit v0.18.0 and its native engine inventory, including configured +// PromptKit v0.20.0 and its native engine inventory, including configured // bundled resources. package ckprompt diff --git a/integrations/ckprompt/go.sum b/integrations/ckprompt/go.sum index 71c885e..85d174d 100644 --- a/integrations/ckprompt/go.sum +++ b/integrations/ckprompt/go.sum @@ -16,8 +16,6 @@ go.maximumdirect.net/commandkit v0.3.0 h1:RCmg2GS8uzlLSJCIqarpn1uFDec0W3ylNNRRPT go.maximumdirect.net/commandkit v0.3.0/go.mod h1:ZS98DewKNVBygKVDoh5MFD09CnPlP37dS9pVsID5Eoc= go.maximumdirect.net/configkit v1.1.0 h1:UzXN2ZMnEkcL0O4YSLqD9qd9M1gb/NWCHQR/H8AaQzA= go.maximumdirect.net/configkit v1.1.0/go.mod h1:s1zLJ9GGB/1Q4a+aOHMLISonJxWFgNWpA6SpPlOafeA= -go.maximumdirect.net/promptkit v0.18.0 h1:mrO+mangAPiR1xdtYjTHemH5xA//waddekVnhI5i0yE= -go.maximumdirect.net/promptkit v0.18.0/go.mod h1:NTdAFcqISmmgiAGch2+s/mHrZTrkUXJYGKc1UfUMF24= go.maximumdirect.net/promptkit v0.20.0 h1:ZpwbjiCZWXdnnZ26RuWKoOco0jFnaAX8m2tQAX7ZlnM= go.maximumdirect.net/promptkit v0.20.0/go.mod h1:kCoyvI0xSax9K9aRPCEkpkyAP5YLs157oBLFLdzgRbM= go.yaml.in/yaml/v4 v4.0.0-rc.6 h1:1h7H1ohdUh93/FyE4YaDa1Zh64K6VVbjF4K6WUxMtH4=