From 29582dd6b73bdb4f1243a24cc1355c02ea725a0a Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 17 Oct 2026 18:10:34 +0000 Subject: [PATCH] Plan dependency upgrades and PromptKit diagnostics --- docs/roadmap/implementation.md | 1272 +++++++++++++++++++------------- docs/roadmap/upgrades.md | 24 +- 2 files changed, 750 insertions(+), 546 deletions(-) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 4f154f1..13f71de 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,482 +1,696 @@ -# PromptKit request validation implementation plan - -Status: Stages 1–9 complete; implementation is complete. - -## Authority, scope, and baseline - -Follow the stages below in order. Each stage is sized for one Luna implementation -prompt and identifies its changes, evidence, and completion condition. The -[accepted feature roadmap](promptkit-validation.md) owns the target state and -user choices. The [architecture policy](../policy/architecture.md), accepted -[ADRs](../adr/), and existing public contracts remain authoritative. - -The planning baseline is commit `1119bda6b720171c708f3e6d03c5c8690b65ea81`. -The implementation now selects released PromptKit v0.15.0; the accepted roadmap -adds `promptkit requirements validate PROMPT_ID`. - -The deliverable is the complete accepted feature, including the independently -optional callback, suite-returning helper, nil-builder path, file bindings, -YAML confirmation, maintained consumer, and canonical documentation. Existing -discovery, catalogs, definitions, configuration operations, and application -commands keep their current contracts. - -## Working instructions - -- Start with [development guidance](../development.md) and applicable policies. - Prefer the repository knowledge graph for code discovery; verify snippets - against current source when graph evidence is incomplete or stale. -- Implement in `integrations/ckprompt`, using public core, ckconfig, ConfigKit, - and PromptKit APIs. Core and ckconfig need no new public API or PromptKit - dependency for this feature. -- Use `Engine.ValidateRequest` directly. Discovery completeness is not a - validation gate. Avoid parallel native validation rules, identity enforcement, - request remerging, automatic execution, or prepared-run retention. -- Preserve caller ownership of callback objects, input, and state. Omitted - factories supply zero values, including nil pointers. No arbitrary deep - copies, automatic pointer repair, or concurrent-dispatch guarantee is added. -- Keep machinery proportionate. Private file and helper names below identify - a concrete implementation route; equivalent simple organization within the - owning package is acceptable. Public names and signatures are settled. -- Apply `gofmt` to changed Go files. Add focused tests alongside the stage that - owns each behavior; reuse existing helpers where useful without duplicating - PromptKit's suite. Current tests are evidence, not a source of new policy. -- Preserve the ignored local workspace and any existing replacements. Do not - commit workspace files or sibling-directory replacements. The selected - upstream PromptKit must be the released v0.15.0 module. -- Commit each completed nonempty stage under the - [agent commit policy](../policy/agents.md#git-commit-policy). Record concise - completion markers and actual validation evidence beneath the corresponding - stage here. Never mark a future stage complete merely because its tests pass - incidentally. Do not push, tag, publish, or rewrite historical release notes - as part of this sprint. - -The validation commands in this plan are for the implementation sprint. This -planning pass creates documentation only. - -## Stage 1: Adopt the released PromptKit dependency and notices - -**Primary files:** `integrations/ckprompt/go.mod`, its `go.sum`, and -`integrations/ckprompt/docs/oss/attribution.md`. - -1. Upgrade only the selected PromptKit requirement to v0.15.0. Keep Go 1.26.0, - ConfigKit v0.7.1, and the existing CommandKit prerequisite version selections. - Review any actual transitive graph changes rather than upgrading unrelated - dependencies. -2. Resolve module metadata with the real released PromptKit. If unpublished - CommandKit prerequisite versions prevent workspace-off operations, use - temporary copies of ckprompt's module and sum files as described under - Stage 9. Add replacements only for core and ckconfig in those copies, run - the targeted upgrade/tidy there, then remove those temporary replacements - before transferring the resulting metadata to the owning checked-in files. - Preserve unrelated existing checksum entries unless normal tidy removes them. -3. Update the **integration's** PromptKit attribution entry from v0.14.0 to - v0.15.0 and pin its source/notice links to - `635674c066d0b432187f96e72b9c03d085443ac5`. The root attribution document is - not the owner of this entry. Review released copyright/license material; - update other entries or texts only for actual changes in selected material. -4. Confirm the released dependency provides `Engine.ValidateRequest` and that - no committed manifest includes a sibling PromptKit replacement. - -**Validation:** Run ckprompt's existing suite with the upgraded dependency; -inspect its selected module version and metadata diff. Use the module practices -in Stage 9 if required. Prose and attribution checks follow -[OSS](../policy/oss.md) and [documentation](../policy/documentation.md) policy. - -**Complete when:** ckprompt selects released PromptKit v0.15.0, its current -suite passes, notices identify that release, and module boundaries are unchanged. - -**Completed:** 2026-10-12. Updated ckprompt to released PromptKit v0.15.0 and -refreshed its integration attribution at commit -`635674c066d0b432187f96e72b9c03d085443ac5`. `GOTOOLCHAIN=local go test --count=1 ./...` passed from `integrations/ckprompt`; `go list -m` selected v0.15.0. -The released source contains `Engine.ValidateRequest`; PromptKit's LICENSE and -COPYRIGHT are unchanged from v0.14.0. The dependency graph, other versions, and -checked-in replacement metadata are unchanged. - -## Stage 2: Add the public capability and bundled validation adapter - -**Primary files:** `integrations/ckprompt/adapters.go`, a new owning-package -`validation.go`, and focused adapter tests. - -1. Add these exact public contracts, with GoDoc: - - ```go - type ValidationRequest struct { - Selection ckconfig.Selection - Request promptkit.RunRequest - } - - // Additional field in Suite[I, S]: - ValidateRequest func( - context.Context, ValidationRequest, I, S, - ) (commandkit.Acquired[struct{}], error) - - func WithRequestValidation[I, S any]( - suite Suite[I, S], - load func(context.Context, ckconfig.Selection, I, S) (*promptkit.Engine, error), - build func(context.Context, ValidationRequest, I, S) (promptkit.RunRequest, error), - ) Suite[I, S] - ``` - -2. Return the supplied suite with its engine-backed `ValidateRequest` callback - attached. Preserve other callbacks, factories, selectors, checks, and - attached issues. With a nil loader, retain a wiring error on the returned - suite and return without constructing a usable new validation callback. - When adding an issue, use an independent issues slice so the operation does - not overwrite a source suite's retained metadata through slice capacity. - Do not deep-copy caller-owned callback objects or selector bindings here. -3. Leave `FromEngine`'s existing five capabilities unchanged. A nil builder is - valid and means forwarding the seed request unchanged. -4. The attached callback checks cancellation before building, uses the builder - if present, checks cancellation again after successful building, acquires - the engine through `loadPromptKitEngine`, and invokes - `engine.ValidateRequest(ctx, concreteRequest)`. Pass the same `I`, `S`, and - invocation context to builder and loader. Use the envelope's original - configuration selection for loading. -5. A builder failure returns its supported error identity and prevents engine - loading. A loader failure returns the acquired configuration diagnostics and - error. A native failure returns that error with the acquired diagnostics. - Check operation errors before substituting a later context error, preserving - PromptKit's native cancellation category. Reuse `promptKitContextError` and - the existing engine-loading diagnostic adaptation where applicable. -6. Treat `Acquired[struct{}]` as diagnostics plus an empty value, not a Boolean - result or nil-result protocol. Builder output is the authoritative concrete - request: forward it without reapplying seed fields, merging maps, or checking - its prompt identity independently. Successful builder calls have no separate - diagnostic-return field in this selected API. - -**Validation:** Add direct adapter tests for composition preserving existing -suite members, nil-builder success, builder failure before loading, and retained -nil-loader issues. Confirm installation reports retained issues even after all -capabilities are cleared. Run the focused tests and ckprompt suite. - -**Complete when:** the public API and adapter work without command dispatch, -with explicit capability opt-in and the selected wiring/error behavior. - -**Completed:** 2026-10-12. Added `ValidationRequest`, the optional suite callback, -and `WithRequestValidation`. The callback forwards a nil-builder seed through -PromptKit validation, preserves original selection and invocation objects, and -retains configuration diagnostics. Adapter tests cover suite composition, -successful nil-builder validation, builder failure before loading, independent -retention of nil-loader issues, and installation reporting after capabilities -are cleared. Focused adapter tests and -`GOTOOLCHAIN=local go test -count=1 ./...` passed from -`integrations/ckprompt`. - -## Stage 3: Verify native delegation, request construction, and cancellation - -**Primary files:** a focused `integrations/ckprompt/validation_adapters_test.go` -or equivalent owning adapter tests. - -1. Use a real offline PromptKit engine with synthetic prompts/profiles and a - counting or fail-on-call model client. Demonstrate successful concrete - validation and a missing required binding, asserting zero model calls. -2. Compare representative adapter failures with native `ValidateRequest` using - the same concrete request, or assert the documented native category with - `errors.Is`. Cover an invalid selection and missing/unloadable artifact - without reproducing every native preparation rule. -3. Demonstrate that a builder receives the seed, context, selection, typed input, - and shared state, then can add inline bindings and request settings. Use an - observable native effect, such as supplying a needed variable/artifact or - invalid appended message, to detect discarded builder output. The adapter - must not silently restore seed fields afterward. -4. Cover a nil engine result and a loader's real `*configkit.LoadError`, including - its retained diagnostic records and error identity. Reuse the existing - fixture and diagnostic helpers rather than a new abstraction framework. -5. Cover cancellation before building, after successful building, and during - or after loading. Verify later work is skipped and already acquired - diagnostics survive. For cancellation returned during native artifact - loading, assert PromptKit's applicable operation category; do not require - a general `errors.Is(err, context.Canceled)` relationship for native errors. - -**Validation:** Run these focused adapter tests and the ckprompt suite. Prefer -behavioral assertions; exact ordering assertions belong only to the explicitly -selected builder-before-loader lifecycle. - -**Complete when:** the adapter's native authority, builder forwarding, failure -handling, and cancellation boundaries have meaningful public-boundary evidence. - -**Completed:** 2026-10-12. Added real-engine adapter coverage for native success, -missing required input, invalid profile, and an unloadable file reference. The -builder test supplies a required inline artifact and verifies context, selection, -typed input, and state reach both callbacks; validation succeeds without a model -call. Tests cover nil engines, retained `*configkit.LoadError` diagnostics and -identity, cancellation before and after building, cancellation during and after -loading, and PromptKit's native artifact-load category when an artifact reader -returns cancellation. Focused adapter tests and -`GOTOOLCHAIN=local go test -count=1 ./...` passed from -`integrations/ckprompt`. - -## Stage 4: Implement the validate command and requirements group composition - -**Primary files:** `integrations/ckprompt/command.go`, a new private -`validation_command.go` in the same package, and basic command tests. - -1. Include `Suite.ValidateRequest` in `Command`'s capability/absence check. - Assemble one `requirements` group from the independently supplied show and - validate declarations. Continue attaching retained suite issues and using - the existing root-only family declaration. Update help summaries to describe - inspection and validation without changing catalog/definition routing. -2. Introduce a private per-invocation validation input holding `ValidationRequest`, - the format, captured selector values, and prepared application input. Build - a normal typed `CommandSpec` named `validate`, with one required prompt ID. - Use `CaptureFlags` and `prepareSuiteInput` for application selectors/checks. -3. Bind the following fields; defaults and repetition follow the accepted - roadmap and current requirements bindings: - - | CLI input | Destination | - | --- | --- | - | Prompt ID operand | `Request.PromptID` | - | `--config`, `--overlay` | Presence-aware `Selection.Config`, `Selection.Overlay` | - | `--version` | `Request.PromptVersion` | - | `--profile` | `Request.ProfileID` | - | `--session-id` | `Request.SessionID` | - | Repeatable `--var KEY=VALUE` | `Request.Vars` | - | Repeatable `--input NAME=PATH` | `Request.Inputs[NAME] = promptkit.File(PATH)` | - | `--format` | Private format, default `yaml` | - | Suite selectors | Captured bindings applied to initialized `I` | - -4. Parse file assignments at the first `=` and preserve the name and path - exactly. Parse every occurrence, then let the last duplicate name win. - Missing separators are usage errors; empty names/paths go to native - validation. Do not read files, normalize paths, expand them, or rebase them - while binding. Reuse variable-assignment mechanics where this is simple, - keeping their existing behavior unchanged. -5. Reject unsupported formats before application input preparation. Use the - existing YAML-only format check where appropriate. Missing operands, - malformed bindings, and unknown flags retain existing usage handling. -6. In the handler, check cancellation, initialize state using the existing - zero-value convention, check cancellation again, and invoke the captured - validation callback. On error, return `definitionFailure` with diagnostics. - After successful validation, check cancellation before encoding/delivery. - A successful empty acquisition value is valid; there is no inspection value - to require or dereference. -7. Encode a private YAML DTO with explicit `prompt_id` and `valid` fields. Use - the command's requested ID and `valid: true`, with no resolved metadata or - request dump. Reuse `encodePromptYAMLBytes` and `writePromptReport`, returning - diagnostics for core delivery. Do not change established report/diagnostic - delivery order, short-write handling, or failure bookkeeping. - -**Validation:** Add a basic assembled command test with a capturing custom -callback and semantic YAML decoding. Verify the correct seed reaches the -callback, and both show and validate can be installed in one requirements group. -Run focused tests and the ckprompt suite. - -**Complete when:** the new command invokes the selected provider and produces -the agreed YAML confirmation using existing core mechanics. - -**Completed:** 2026-10-12. Added `requirements validate` with typed selector -preparation, presence-aware configuration selection, PromptKit request flags, -repeatable variable and file bindings, and YAML confirmation output. `Command` -now composes supplied show and validate declarations in one requirements group -and retains issue reporting for absent capabilities. The assembled command test -verifies callback values, first-`=` file paths, semantic YAML output, and both -operations in help. Focused command tests and -`GOTOOLCHAIN=local go test -count=1 ./...` passed from -`integrations/ckprompt`. - -## Stage 5: Cover command grammar, capability availability, and input lifetimes - -**Primary files:** a focused `integrations/ckprompt/validation_command_test.go` -and existing requirements command tests where an extension is simpler. - -1. Exercise validation-only, discovery-only, both, and absent suites. Check - installed help/availability and the existing namespace collision/root-only - behavior for the new validation-only declaration, reusing core coverage - rather than retesting the registry in full. -2. Verify construction, installation, help, and version leave input/state - factories, builders, and loaders uninvoked. Capture a command, then mutate - source callbacks/selector metadata to confirm the established eager-capture - behavior includes the new callback. Callback-owned referenced objects stay - caller-owned. -3. Capture standard request fields and typed selectors in a custom provider. - Cover explicit empty config/overlay presence, empty scalar native semantics, - singleton repetition, and repeated variable/file assignments. Include paths - containing `=`, empty names/values, whitespace/commas, duplicate names, and - a malformed earlier occurrence followed by a valid one. Inspect native file - references without requiring nonexistent paths to pass actual validation. -4. Cover missing/extra operands, unsupported format, unknown flags, malformed - `--var`/`--input`, and required suite selectors. Confirm applicable syntax - failures stop before application preparation/acquisition. Input-check - failures stop state creation and provider work using current classifications. -5. Run multiple invocations on one App and verify parsed Vars/Inputs, selection, - and selector presence do not leak into later calls. Verify one reached input - preparation/check and state creation per selected validation invocation, - and omitted factories supply zero values including nil pointers. Do not - promise isolation for aliases created by application factories. - -**Validation:** Run the focused command tests and ckprompt suite. Decode each -YAML output into a fresh value; avoid output-prefix or key-order assertions. - -**Complete when:** the new capability obeys the selected standard grammar, -availability, capture, and invocation-lifetime contracts. - -**Completed:** 2026-10-12. Added validation-only availability, namespace -collision and root-only placement coverage; construction/install/help/version -callback timing; eager callback and selector capture; exact standard request, -selector, empty-presence, repeated-assignment, first-`=` file, and duplicate -last-wins behavior; repeated-invocation isolation; usage preflight; input-check -failure ordering; and nil-pointer zero-value factories. A missing required -captured selector is a usage outcome before `Suite.CheckInput`, state creation, -or provider work. Under the existing `CaptureFlags`/`prepareSuiteInput` flow, -`Suite.NewInput` runs before `FlagValues.ApplyTo` reports that missing selector. -Focused validation command tests and -`GOTOOLCHAIN=local go test -count=1 ./...` passed from -`integrations/ckprompt`. - -## Stage 6: Cover native command outcomes and report delivery - -**Primary files:** validation command tests and small real-engine fixtures. - -1. Exercise `WithRequestValidation` through `Command` and `App.Execute`, with - real native success, missing required binding, and one selection failure. - Include a useful nil-builder request built entirely from standard flags. - Assert no model call and preserve native error identity; compare categories, - not exact human-readable error wording. -2. Cover custom-provider diagnostics on success and error. Builder, loader, - and native failures are operational outcomes/status 1. CLI usage failures - are status 2. Retain warning diagnostics without turning warning severity - alone into failure. Reuse existing input-check handling. -3. Verify cancellation before acquisition and after a successful callback - prevents later work/report output. Preserve callback errors and native error - categories rather than overwriting them with a general context error. -4. Reuse existing writer doubles to cover report errors, short writes, and - diagnostic writer errors. Preserve `ReportIncomplete`, `DeliveryError`, - diagnostic-delivery state, and supported cause identity as established by - the shared delivery contract. Do not add rollback or blocking-writer - interruption guarantees. -5. Decode the success report and assert only the agreed confirmation fields - are emitted, without values/artifact contents/rendered messages. Keep the - existing partial-discovery-success tests as regression coverage; do not - duplicate their whole matrix for validation. - -**Validation:** Run focused tests and the complete ckprompt suite, including -its maintained composed consumer tests. - -**Complete when:** assembled validation follows native semantics and existing -outcome/report delivery contracts under representative successes and failures. - -**Completed:** 2026-10-12. Exercised the composed command with real PromptKit -success, missing required input, and invalid profile selection; success emits -only `prompt_id` and `valid`, and the fail-on-call model client remains unused. -Command tests cover builder, ConfigKit loader, custom provider, and native -failures; warning diagnostics on success and error; cancellation before and -after acquisition; callback-error precedence; report writer errors, short -writes, and diagnostic writer errors with the established outcome fields. -Focused outcome tests and `GOTOOLCHAIN=local go test -count=1 ./...` passed from -`integrations/ckprompt`. - -## Stage 7: Extend the maintained composed consumer - -**Primary files:** `integrations/ckprompt/examples/composed/main.go`, its tests, -README, and synthetic fixtures under its existing `fixtures/` directory. - -1. Compose `WithRequestValidation` into the existing `FromEngine` suite, keeping - its factories, campaign selector, catalogs, definitions, discovery, and - separately installed config/session commands. -2. Add a typed builder that starts from the seed and uses the existing - application configuration loader and invocation cache. Load the selected - campaign through that shared state, then default a missing `topic` variable - to a synthetic campaign-specific topic and missing `mode` to `""`. Use map - membership, preserving supplied empty values. Keep seed identity, scalar - context, and operator artifact bindings. The engine loader can then reuse - that application load through the same cache. This is example behavior, - not a CommandKit cache/defaults policy. -3. Keep the existing synthetic prompt template and required `topic` artifact. - Add secret-free `fixtures/topic.txt` and `fixtures/notes.txt`. Do not supply - the required topic artifact implicitly in the builder: its absence is the - useful validation failure. The existing profile uses an inert endpoint and - no real credentials; validation remains offline. -4. Add README commands, from the composed directory: - - ```sh - go run . promptkit requirements validate briefing --campaign spring --input topic=fixtures/topic.txt - go run . promptkit requirements validate briefing --campaign spring --input topic=fixtures/topic.txt --var mode=full --input notes=fixtures/notes.txt --format yaml - go run . promptkit requirements validate briefing --campaign spring - ``` - - The first two succeed; the last intentionally fails for the missing required - topic binding. Preserve the existing show examples, explaining their distinct - discovery result. Describe success as passing preparation at that invocation. -5. Add focused composed-consumer evidence for successful file-backed validation, - missing-topic failure, and the builder preserving explicitly empty variables - while supplying defaults only for absent keys. Test builder behavior directly - where needed to observe precedence without inventing a library enforcement - rule. Preserve current campaign and discovery tests. - -**Validation:** Run composed tests and the documented successful/failing -commands. Record the expected classifications and semantic reports rather than -making the intentionally failing example a failed completion check. - -**Complete when:** the maintained consumer demonstrates the accepted feature, -typed selection, shared state, and application-owned defaults without execution. - -**Completed:** 2026-10-12. Composed `WithRequestValidation` with the existing -engine loader, campaign selector, input/state factories, and invocation cache. -The typed builder loads the selected campaign through that cache and defaults -only absent `topic` and `mode` variables, preserving explicit empty values and -operator bindings. Added offline topic and notes fixtures and extended the -consumer README with both successful file-backed commands and the intentional -missing-topic failure. Composed tests passed with -`GOTOOLCHAIN=local go test -count=1 .`; both successful README commands emitted -the expected two-field YAML confirmation, and the missing-topic command exited -with status 1 for the native required-artifact error. - -## Stage 8: Update canonical documentation for implemented behavior - -**Primary files:** GoDoc, `docs/cli.md`, `docs/consumers/guide.md`, README, -`docs/development.md`, and `docs/internal/overview.md` as affected. - -1. Complete GoDoc for `ValidationRequest`, `Suite.ValidateRequest`, - `WithRequestValidation`, and command factory behavior. Update the existing - `InspectRequirements` comment so omission refers to `requirements show`, - rather than implying the entire requirements group is absent. State optionality, - nil-builder forwarding, retained wiring issues, builder-before-loader order, - callback ownership, and native error/diagnostic treatment. -2. Extend the CLI requirements section with separate show/validate descriptions, - exact flags and repetition rules, file-binding semantics, YAML confirmation, - and status meanings. Scope existing discovery-only statements appropriately: - concrete validation loads resources and renders through native preparation; - it returns encountered errors and no snapshot/model output. -3. Update consumer guidance from five independently optional callbacks to six, - distinguishing `FromEngine`'s five supplied callbacks from explicit validation - composition. Include minimal full-suite and validation-only/nil-builder - wiring, and link to the maintained consumer for the complete builder example. - Recommend shared validation/execution request construction without prescribing - downstream architecture. -4. Update module summaries and implemented internal inventory to include concrete - validation. Audit statements about no rendering/resource loading/credential - resolution so metadata-inspection descriptions do not accidentally cover the - new capability. Keep native semantics linked to adopted upstream contracts. -5. Leave accepted ADRs, policy boundaries, historical releases, and unrelated - deferred proposals intact. No new ADR or policy revision is required by this - accepted feature. Current API/CLI documentation becomes the canonical owner - when implementation lands. - -**Validation:** Review examples against implemented signatures and commands; -check local links/anchors and Markdown whitespace. Reuse Stage 7's unchanged -example evidence. Check prose for accidental stronger guarantees or consumer -mandates. - -**Complete when:** current documentation accurately describes the implemented -capability under its assigned owners, with no stale five-callback or -metadata-only claims covering request validation. - -**Completed:** 2026-10-12. Updated ckprompt GoDoc, the CLI reference, consumer -guidance, README module summary, development orientation and examples, and the -internal component inventory. The docs distinguish `FromEngine`'s five -callbacks from explicit validation composition, describe native preparation and -the minimal success YAML, and scope discovery-only statements to discovery. -`GOTOOLCHAIN=local go test -count=1 ./...` passed from `integrations/ckprompt`; -the Stage 7 consumer tests and commands remain unchanged and passed. Changed -Markdown links and anchors and Markdown whitespace checks passed. - -## Stage 9: Validate the complete end state and finish - -1. Format changed Go files and inspect the final diff for scope, generated junk, - local replacements, and unrelated changes. Keep `deferred.md` intact unless - a statement actually becomes stale through this feature. -2. Run the complete workspace suites from all three module directories: +# Dependency upgrades, discovery, and smoke testing implementation plan + +Status: ready for implementation; no stages have started. + +## Authority and baseline + +Implement the [accepted upgrade roadmap](upgrades.md) by following Stage 1 +through Stage 18 in order. Each stage is sized for one Luna coding prompt. +The roadmap owns the selected target and intent; this plan specifies the work +to reach it. The [architecture policy](../policy/architecture.md), accepted +[ADRs](../adr/), and applicable policies remain authoritative. + +The planning baseline is `38b49f29fb3a8f22ff02528d2a0ed413e5c6ab1e`. +It has ReleaseKit v0.4.0 at the root, ConfigKit v0.7.1 in both integrations, +and PromptKit v0.15.0. The target releases are ReleaseKit v0.4.2, ConfigKit +v0.8.0, and PromptKit v0.16.0, at the exact upstream revisions recorded in the +roadmap. The Go consumer minimum remains 1.26.0 and the selected maintainer +toolchain remains 1.26.8. + +This plan replaces the completed request-validation implementation plan, which +remains available in [Git history](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/38b49f29fb3a8f22ff02528d2a0ed413e5c6ab1e/docs/roadmap/implementation.md). +That feature is baseline behavior to migrate, not an unfinished assignment. + +## Working rules + +- Start with [development guidance](../development.md) and its policy reading + guide. Prefer the knowledge graph for code discovery; use current source when + graph evidence is incomplete. +- Deliver the complete roadmap in one coordinated sprint. Intermediate commits + need not build; stages identify useful units of work, not compatibility + layers or independently releasable intermediate APIs. Preserve established + contracts except where the accepted roadmap deliberately changes them. +- Keep core independent of optional libraries. ckconfig owns ConfigKit + adaptation; ckprompt may use ckconfig. Do not introduce the reverse + dependency or expose Cobra/pflag types. +- Use released upstream modules. Adjacent checkouts are review evidence, not + committed replacements or sources of internal imports. +- Implement straightforwardly in the owning packages. Private file names below + are suggested organization; do not create frameworks, exported abstractions, + or additional internal layers merely to match the plan. +- Retain application ownership of factories, callbacks, configuration policies, + credentials, defaults, and returned objects. No arbitrary deep copies, + pointer repair, new caching policy, or concurrency guarantee is selected. +- Apply the [upstream testing ownership boundary](../policy/testing.md#upstream-integration-testing-ownership). + Test CommandKit's forwarding, coordination, presentation, and outcomes. + Do not independently verify upstream composition, namespace resolution, + prompt preparation, provider diagnostics, or inference correctness. +- Use small test doubles at external boundaries and real upstream fixtures + where useful. This does not require production mocking interfaces. Default + tests remain offline and credential-independent. +- Format changed Go files. Run focused checks appropriate to each stage; + broad integration checks follow when the affected migration is coherent. + Record actual completion evidence and commit each completed nonempty unit + under the [agent policy](../policy/agents.md#git-commit-policy). +- This sprint does not publish releases, create tags, choose future module + release numbers, or add release gates. Release preparation remains governed + by the existing release procedure. + +## Implementation choices used by the stages + +These details complete the accepted target for coding. They define this +implementation's shape, not new cross-library domain policy. + +### Catalog requests and callbacks + +Introduce two small public request types in ckprompt: + +```go +type CatalogRequest struct { + Selection ckconfig.Selection + Filter promptkit.NamespaceFilter +} + +type NamespaceRequest struct { + Selection ckconfig.Selection + Kinds []promptkit.ResourceKind +} +``` + +Use `CatalogRequest` for `Suite.ListPrompts`, `Suite.ListProfiles`, and the new +`Suite.ListBackends`. Use `NamespaceRequest` for the new `Suite.ListNamespaces`. +`Suite.ListCollections` takes the existing `ckconfig.Selection` directly: +its native operation has no resource filter to wrap. + +All callbacks retain their existing context, typed input `I`, shared state `S`, +and `commandkit.Acquired[T]` plus error pattern. Result types are: + +| Callback | Acquired value | +| --- | --- | +| `ListPrompts` | `[]promptkit.PromptIdentity` | +| `ListProfiles`, `ListBackends`, `ListNamespaces` | `[]string` | +| `ListCollections` | `[]promptkit.CollectionInfo` | + +`FromEngine` supplies the original inspection operations and all five catalogs: +eight independently optional callbacks in total. Request validation and smoke +testing are added explicitly by their respective helpers, giving ten possible +suite capabilities. No universal operation registry is needed. + +For the filterable catalogs, forward the native `Filter` to the corresponding +listing method, including the zero-valued `NamespaceDefault`. For namespaces, +forward `Kinds...` without implementing union, membership, or sorting locally. + +### Report shapes + +Keep existing report organization except for the accepted changes and additions: + +- `config sources` retains its scope/source structure. Add `destination` as the + native canonical JSON Pointer, `placement` as `mapping` or `sequence_item`, + `destination_unresolved` as a boolean, and nullable `version_check`. + Its nested fields are `path`, `version` (`present`, `null`, `text`), + nullable `location` (`source_id`, `line`, `column`), and `redacted`. + Preserve false, empty, and null native values. Text exposes the same evidence. +- Prompt inspection, requirements inspection, and prompt catalog entries use + `version` as `*string` with YAML `omitempty`. Nil omits the field; a pointer + to `""` emits an empty string. Text inspection omits an absent version and + quotes a present empty version. +- Profiles, backends, and namespaces are bare YAML string sequences. + Prompt entries remain `{id, version?}`; collection entries are + `{namespace, version?}`, projecting native `ReleaseVersion` into `version`. + Preserve provider order and exact identities. Nil/empty inventories emit `[]`. +- A single smoke test emits the native report projected into a private YAML DTO. + Use snake_case native field names, with descriptive `PromptVersion` rendered + as optional `version` inside its target under the accepted version convention. + Include all report fields and their native nested evidence; do not serialize + the request or engine. +- Aggregate smoke output is one YAML mapping with `tests`, an ordered sequence + of entries containing `kind`, nullable `report`, and optional `error` text. + The outer `kind` identifies the selected concrete operation; a non-nil native + report retains its own returned `kind`. No extra readiness summary is added. + Include attempted operations only after cancellation stops the sequence. + +For smoke DTOs, preserve scalar zero values, nullable tri-state observations, +settings-presence booleans, and token counts' `value`/`known`/`complete` fields. +Render `time.Time` through the existing YAML encoder and durations as Go +duration strings, preserving nil duration pointers as null. Render an empty +attempt list as `[]`. Keep native effective settings and `extra_params` data; +do not introduce a second sensitivity classification. + +The aggregate `error` is presentation text, not a serialized Go error object or +a replacement for the returned error's identity. For a single test, deliver any +returned report and use existing diagnostics for the operation error. If a +callback returns neither a report nor an error, report an operational provider +contract failure rather than dereferencing nil or fabricating native evidence. + +### Smoke invocation and delivery + +Use the roadmap's `SmokeRequest` envelope, optional `Suite.SmokeTest` callback, +and `WithSmokeTesting(suite, load, build)` helper. The callback represents one +concrete operation, for both single and aggregate invocations. + +The helper's builder runs before its engine loader, as in request validation. +A nil builder forwards the seed; a supplied builder's complete native request +is authoritative. Return the native report and error together. Retain acquired +diagnostics. A nil loader attaches an installation issue even if the capability +is subsequently removed, following the existing suite convention. + +For `all`, the handler prepares input/checks/state once, then invokes the +captured concrete-test callback sequentially. The per-test seed varies `Kind`; +the optional builder sees each concrete seed. Keep the native request returned +by the builder authoritative, including its application-owned choices. +Engine reuse can occur through application shared state; do not add an +integration cache or make loader-call counts a public requirement. + +Collect reports and errors, then encode and deliver one report. Continue after +individual operation errors unless canceled. On cancellation, stop scheduling, +retain acquired results, and return operational cancellation with supported +identity. Never add synthetic results for operations that did not run. + +Join multiple operation causes using `errors.Join`, preserving `errors.Is` and +`errors.As` access. Keep diagnostic records in returned order and let the +existing invocation coordinator deliver them. Do not add duplicate error +diagnostics on top of the coordinator's existing presentation. + +Smoke report delivery must attempt available output even when the context has +become canceled; the success-only `writePromptReport` cannot be used unchanged. +Retain operation causes if encoding or delivery also fails. Report writer +errors/short writes through `DeliveryError` and `ReportIncomplete` under the +existing outcome contract. Do not change unrelated inspection delivery or add +rollback/blocking-writer interruption promises. + +A nil native error and successful delivery yield success for a single operation. +For `all`, every selected operation must return without error and delivery must +succeed. Cancellation and operational/delivery errors yield the established +operational classification. Native false, unknown, unsupported, or incomplete +observations do not independently change the outcome. + +## Stage 1: Adopt ReleaseKit v0.4.2 + +**Primary files:** root `go.mod`/`go.sum`, root attribution, +`docs/policy/release.md`, `docs/release.md`; existing launcher/tests for review. + +1. Update the root tool requirement to released ReleaseKit v0.4.2 and obtain real + checksums. Preserve the Go minimum and release toolchain. +2. Update the root selected-component attribution and pinned notice/source links + for the adopted revision. Compare applicable upstream notices; preserve + unchanged license texts. +3. Update factual tool-version and commit-pinned reference links in the release + policy and runbook. Leave their publication contracts unchanged. +4. Review `scripts/release` and its three profiles against the adopted public + contracts. Keep the existing launcher, bootstrap storage, shared files, and + source-only publication behavior unless a concrete compatibility defect + requires correction. Do not add Woodpecker workflows or hosted deliverables. + +**Validation:** Run existing launcher argument/delegation tests and the root +default suite as appropriate. Assert CommandKit's invocation contract, not +ReleaseKit's publication algorithms. Do not invoke publication. + +**Complete when:** the root selects v0.4.2 and its factual notices/references +agree, without new release machinery. + +## Stage 2: Adopt ConfigKit v0.8.0 in both integrations + +**Primary files:** integration manifests/sums, ConfigKit adapters and affected +literals, both integrations' attribution. + +1. Set both direct ConfigKit requirements to v0.8.0. Prepare actual sums under + each module's own graph; preserve released PromptKit v0.15.0 until Stage 4. +2. Review ConfigKit-facing code for unkeyed `SourceInfo` literals, equality, + or map-key use affected by its new noncomparable `Path` field. Adapt actual + uses without inventing an equality abstraction or changing source identity. +3. Preserve native `Result`/inspection records through existing providers. + Destination, placement, version checks, and sequence composition remain + available through application loader options, not new generic CLI policies. +4. Update ConfigKit attribution for both modules with the reviewed v0.8.0 + revision and applicable notices. + +**Validation:** Run ckconfig's existing suite and build affected ckprompt code +where its still-old PromptKit API permits. Review selected dependency versions. +Do not add native placement/composition/version-check feature matrices. + +**Complete when:** both integration manifests name v0.8.0 and the existing +ConfigKit boundary remains coherent. + +## Stage 3: Extend configuration source reports + +**Primary files:** `integrations/ckconfig/sources.go` and focused source-report +tests, reusing the existing native source-reader boundary. + +1. Extend `sourceDTO` and text rendering with the fields and nested shape + specified above. Convert native paths with `Path.String()`, and map the two + native placement modes to their corresponding names. +2. Project `SourceVersionCheck` only from returned native records, preserving + native optional locations and sanitized version values. Do not reread files, + rerun checkers, or derive acceptance/validation judgments from the evidence. +3. Keep existing source fields, inventory order, scope behavior, source-reader + capability handling, and delivery paths. Keep `config explain` and compact + diagnostic legends focused on their existing responsibilities. +4. Add focused report tests using controlled returned `SourceInfo` values: + root/non-root destination, both placement modes, unresolved false/true, + absent/present version evidence, nil/non-nil location, and meaningful + present/null/text/redacted values. These test projection, not native + sanitization or source resolution. + +**Validation:** Decode YAML semantically and inspect text fields without key-order +or whole-output snapshots. Run focused source tests and the ckconfig suite. + +**Complete when:** both source formats expose the agreed native evidence with no +parallel ConfigKit behavior. + +## Stage 4: Migrate ckprompt production code to PromptKit v0.16.0 + +**Primary files:** ckprompt manifest/sums, `adapters.go`, `command.go`, +`validation.go`/`validation_command.go`, affected report DTOs, attribution. + +1. Select released PromptKit v0.16.0, retaining direct ConfigKit v0.8.0. + Update the PromptKit attribution to its reviewed release revision. +2. Remove `PromptRequest.Version` and the prompt-only `--version` bindings from + named prompt inspection, requirements show, and requirements validate. + Remove corresponding fields/assignments in native request seeds. +3. Call `InspectPrompt(ctx, request.ID)` and forward the revised native + requirements/run request types. Retain configuration selection, context, + selectors, builders, diagnostics, and native error identity. +4. Update named/requirements/catalog report DTOs to optional `version` fields + and adapt text presentation, using the report choices above. Do not use + label values for selection or convert nil to empty strings. +5. Review remaining production uses of removed catalogs, implicit profiles, + or old upstream fields and migrate those actual uses. + +**Validation:** Build the production ckprompt package against the selected +released dependencies. Test fixtures and consumer code are migrated in Stage 5; +do not create compatibility shims solely to make this intermediate stage green. + +**Complete when:** production adaptation uses the new ID-only API and optional +version representation. + +## Stage 5: Migrate existing fixtures, tests, and composed loading + +**Primary files:** ckprompt tests, `examples/composed/main.go` and fixtures, +their tests. + +1. Convert native version-keyed prompt mappings to one direct definition per ID. + Retain useful versions as optional metadata. For tests that genuinely need + multiple resources, use distinct IDs rather than rebuilding version lookup. +2. Make needed backend/profile definitions explicit. Remove expectations about + installed catalogs and former standard/auto profiles. Use small synthetic + inputs; do not adopt external catalogs just to restore old fixtures. +3. Update the composed engine mapping to the direct prompt-definition format. + Keep its existing campaign selector, request builder, config scopes, state + cache, and session command. Its application `prompt_version` data may remain + descriptive input, used to populate native `version`, without selecting a + definition. Do not require a campaign-loader redesign or collections demo. +4. Update tests for ID-only requests and removed flags. Add focused projection + evidence for absent, present-empty, and nonempty `version` across the + affected reports; verify absent keys rather than YAML null. +5. Replace obsolete upstream-domain assertions encountered in these affected + tests with CommandKit boundary assertions. Preserve meaningful adapter + protection; do not expand this into a repository-wide test rewrite. + +**Validation:** Run ckprompt's existing suite, including the composed consumer. +Exercise a named inspection and requirements show/validate through the updated +fixture. Native errors may be fixtures; assertions protect forwarding, report +presentation, and error identity, not upstream detection algorithms. + +**Complete when:** the previous delivered feature set works through v0.16.0 +without compatibility scaffolding or implicit catalogs. + +## Stage 6: Extend catalog contracts and engine adapters + +**Primary files:** ckprompt public request declarations, `Suite`, `FromEngine`, +and focused adapter tests; `catalog.go` is a suitable private organization. + +1. Add `CatalogRequest` and `NamespaceRequest` as specified above, revise + existing prompt/profile callback signatures, and add backend, namespace, + and collection callbacks. +2. Extend `FromEngine` to forward the correct request fields to each native + API. Continue using `loadPromptKitEngine` for selection and diagnostics. + Forward native filters/kinds and returned results/errors directly. +3. Preserve native engine views from loaders. Do not reconstruct views, + qualify IDs, filter lists, calculate namespace unions, or sort memberships. +4. Migrate existing custom catalog callbacks and call sites to the new request + signatures. Add GoDoc for request fields, native defaults, and independent + optionality. Keep nil-loader issue retention. +5. Use focused adapter evidence: direct native-call parity on a small fixture + can establish forwarding. Test selector/state/context propagation and loader + diagnostics/error identity through existing seams without creating a + parallel namespace semantics matrix. + +**Validation:** Build ckprompt and run focused adapter tests. Current command +call sites may need their mechanical signature adaptation here, with new +operator syntax delivered in Stage 7. + +**Complete when:** all five catalogs are available through narrow native adapters +and public callback shapes are coherent. + +## Stage 7: Add catalog command bindings and YAML output + +**Primary files:** ckprompt catalog command construction, input preparation, +encoders, and basic assembled command tests. + +1. Install each supplied catalog independently under `promptkit list`. Extend + empty-suite detection and group assembly to include the new callbacks. + Keep eager metadata/callback capture, root-family ownership, and retained + assembly issues. +2. For prompts/profiles/backends, add singleton `--namespace` and boolean + `--all-namespaces`. Map omitted selection to `NamespaceDefault`, a supplied + nonempty name to `NamespaceNamed`, an explicit empty name to + `NamespaceUnqualified`, and true `--all-namespaces` to `NamespaceAll`. +3. An active all-namespaces choice plus supplied namespace is a usage error + before provider work. Explicit `--all-namespaces=false` does not select + an override; combine it with namespace or retain native default normally. + Preserve singleton last-occurrence and namespace presence behavior. +4. For namespaces, add repeatable `--kind`, preserving supplied native + `ResourceKind` values and forwarding the slice. Omission forwards the native + union/default. For collections, add no namespace/kind membership filter. +5. Retain common selection/selectors and YAML-only format preflight. Use normal + string-to-native-type conversion; leave native name/kind validity to + upstream APIs rather than duplicating domain validation. +6. Add collection projection and reuse string-list rendering for profiles, + backends, and namespaces. Follow the report shapes above, without local + membership reinterpretation. + +**Validation:** Add basic capturing-callback command tests for each new operation, +filter conversion, and collection optional versions; run focused catalog tests. + +**Complete when:** the accepted catalog CLI and reports invoke the intended +callbacks through the standard binding system. + +## Stage 8: Verify discovery availability, lifetimes, and outcomes + +**Primary files:** focused ckprompt catalog command/adapter tests. + +1. Cover absent and independently supplied catalogs, help without acquisition, + retained wiring issues, and eager capture for new callbacks. Reuse existing + registry coverage rather than reproducing its full collision matrix. +2. Capture callback requests for native default/named/unqualified/all choices, + explicit false, conflicting active choices, singleton repetition, and + repeatable kinds. Assert original selection, selectors, context, and state. +3. Cover missing required selectors, extra operands, unsupported format, + unavailable flags, and input-check failures. Assert no provider work where + required, without insisting on factories running after an earlier failure. +4. Verify fresh parsed values across repeated invocations, nil-factory zero + values, native inventory order/strings, empty sequences, optional versions, + and representative error/cancellation/diagnostic/write outcomes. + +**Validation:** Run focused discovery tests and the ckprompt suite. Use synthetic +returned inventories for report/membership assertions; these tests do not +establish native namespace algorithms. + +**Complete when:** discovery exposes only declared capabilities and preserves +the selected CommandKit invocation contracts. + +## Stage 9: Add the optional smoke capability and native adapter + +**Primary files:** ckprompt `Suite`, new `smoke.go` or equivalent, adapter tests. + +1. Add `SmokeRequest` and `Suite.SmokeTest` with the roadmap's signatures. + Ensure the acquisition value can retain a report with an error. +2. Add `WithSmokeTesting` preserving the rest of the suite and retained issues. + Capture loader/builder references consistently with existing helpers. +3. Apply the builder-before-loader/nil-builder rules above. Forward the complete + resulting request to `Engine.SmokeTest`, preserving native report and error. + Check cancellation before further acquisition, but do not discard an + error-bearing report through a success-only post-call path. +4. Retain loader diagnostics and nil-engine/nil-loader handling from existing + conventions. Do not call requirements validation, resolve native targets, + implement retries, or derive success from report findings. +5. Add focused helper tests for nil builder, authoritative builder output, + typed input/state/context, builder failure before loading, retained wiring + issues, and report/error propagation. Use a small native engine with an + injected public client where the actual adapter needs exercising. + Observe the forwarded request/effective native call; do not test the private + diagnostic case or provider acceptance behavior. + +**Validation:** Run focused smoke adapter tests and existing adapter suites. +No live provider or real credentials are needed. + +**Complete when:** one concrete smoke request reaches the native API through an +independently optional, composable adapter. + +## Stage 10: Implement faithful smoke YAML projection + +**Primary files:** private `smoke_report.go` and focused projection tests. + +1. Define small private DTOs for the report fields described above. Map every + exported v0.16.0 `SmokeTestReport` field and its nested public data explicitly; + avoid reflect-based conversion, a JSON round trip, and raw request dumping. +2. Include target IDs, optional target version, selection source, endpoint, + effective settings and settings-presence fields; native facts; timing; + attempts; presence-aware token usage; reason/failure values. +3. Preserve nullable booleans and durations, explicit false/zero, empty optional + version strings, unknown token metadata, and `extra_params` values. Use + existing YAML encoding and native types where their representation is + suitable; private DTOs provide naming/formatting only. +4. Add the aggregate envelope with ordered entries and optional error text. + Keep native report data unchanged if its kind differs from the selected + outer kind due to application request construction. +5. Add synthetic-report tests protecting omission, presence, nested values, + durations, empty attempts, all field categories, and report-plus-error + entries. Decode YAML semantically; do not freeze key order or timing values + produced by a live operation. + +**Validation:** Run focused projection tests. Verify no native request/API key is +serialized; do not introduce filtering of returned `ExtraParams`. + +**Complete when:** native smoke evidence and aggregate entries have a complete, +neutral YAML representation. + +## Stage 11: Bind and execute single smoke tests + +**Primary files:** private `smoke_command.go`, `Command` assembly, basic command +tests. + +1. Add one runnable `test` command with one required `KIND` operand. Install it + only when `Suite.SmokeTest` is supplied. Include it in empty-suite detection, + captured suite metadata, and the promptkit family help. Do not add an + application-owned command beneath the family. +2. Bind every scalar/request field in the roadmap table using the existing + typed binding APIs. Use standard integer/floating-point conversion and + presence-aware setters; do not add a second parser or range validator. +3. Construct `Execution` only when at least one execution flag is supplied. + Omitted pointer fields stay nil; supplied zero or empty values remain + present. Bind `TransientRetries` independently. Use native enum strings for + individual kinds. Recognize `all` for Stage 12 expansion before constructing + a native request; never pass that token as a native kind. +4. Apply common selection, captured selectors, YAML-only preflight, input checks, + cancellation checks, and state initialization through existing patterns. + For a single operation, invoke the captured callback once. +5. Use the Stage 10 projection and a focused delivery helper to deliver any + acquired report, even when accompanied by an error/cancellation. Return + diagnostics and outcome fields under the delivery rules above. +6. A nil report with a non-nil error remains an ordinary operation error; emit + no fabricated single native report. Neither nil result with nil error nor + encoding/delivery failure may become success. + +**Validation:** Add basic assembled single-command tests with capturing callbacks, +including successful native findings, report-plus-error, and a short writer. +Run focused smoke command tests. + +**Complete when:** all single-kind bindings invoke the optional provider and +faithfully report its result and errors. + +## Stage 12: Coordinate aggregate smoke execution + +**Primary files:** smoke command runner, aggregate projection/outcome helpers, +focused aggregate tests. + +1. Expand `all` to reachability, authentication, text inference, and structured + output in the accepted order. This is one invocation of the standard command, + not four dispatcher executions. +2. Prepare/check typed input once and create shared state once when reached. + Build a concrete seed for each selected kind, invoking `Suite.SmokeTest` and + therefore the optional builder separately. Keep `all` out of native requests. +3. Preserve the common CLI seed across operations. Construct each per-test seed + from the bound scalar values with its own execution override struct and + fresh pointers for supplied optional controls, including transient retries. + This keeps builder edits to one seed from changing later parsed defaults. + Do not deep-copy application input/state or arbitrary builder objects. +4. Append each acquired report, error, and diagnostics in operation order. + Continue after an individual error. If the caller context is canceled, + stop scheduling further operations, retain results, and preserve cancellation + identity alongside already returned causes. +5. Join errors with the standard library and encode one aggregate document. + Retain each associated error in its entry; preserve supported error identity + in the invocation cause. Do not promote false/unknown report facts to errors + or add an overall readiness score. +6. Deliver retained results despite cancellation, and preserve operation causes + separately from report/diagnostic delivery failures. With no operation + reached because preflight or initial cancellation failed, use the existing + early-failure handling; do not invent native observations. +7. Do not introduce loader memoization, parallel execution, custom retry loops, + synthetic skipped-test statuses, or a second public aggregate callback. + +**Validation:** Use controlled callback results to verify call order, distinct +concrete seeds, shared input/state, continuation, partial errors, cancellation +stopping, ordered output, and joined error identity. Run focused aggregate tests. + +**Complete when:** `promptkit test all` provides the agreed coordination through +the same concrete-operation callback as individual tests. + +## Stage 13: Verify smoke bindings and invocation lifetimes + +**Primary files:** focused smoke command/adapter tests, reusing existing writer +and diagnostic doubles. + +1. Cover native seed fields from all bound flag categories, pointer omission + versus zero/empty, config/overlay presence, singleton last occurrence, + selectors, and per-invocation reset. Verify targets may be combined and + native semantic errors retain operational classification. +2. Cover syntax/conversion/operand/format failures and input-check handling. + Missing operands, malformed numeric syntax, unsupported format, and unknown + flags remain usage failures; factories need not run after failed preflight. +3. Cover a smoke-only suite, absent smoke with other capabilities, installation + issues after narrowing, eager callback/selector capture, and help/version + leaving factories/builders/loaders/providers uninvoked. +4. Verify one input preparation/state lifetime for `all`, nil-factory zero values, + and builders seeing concrete kinds. Check earlier reports remain available + when later operations fail or cancellation stops the sequence. + +**Validation:** Run focused smoke binding/lifecycle tests and the ckprompt suite. +Assert callback requests and invocation state, not native target resolution. + +**Complete when:** the new command obeys selected grammar, presence, capture, +availability, and lifetime contracts. + +## Stage 14: Verify smoke outcomes and report delivery + +**Primary files:** focused smoke outcome tests and existing writer/diagnostic +fixtures. + +1. Cover report-only success, false/unknown native observations with nil errors, + report-plus-error, error-only, and nil-report contract failure. Confirm + supported native and cancellation error identity survives aggregation. +2. Cover cancellation before acquisition, after partial results, and between + tests. Verify available reports are delivered and no later callback starts + after cancellation is observed. Do not assert interruption of an already + running caller callback or blocking writer. +3. Cover encoding failures, report writer errors/short writes, diagnostic writer + failures, and operation plus delivery errors. Retain `Cause`, `DeliveryError`, + `ReportIncomplete`, and diagnostic delivery state as applicable. Reuse shared + coordinator coverage for unchanged mechanics. +4. Verify aggregate error entries correspond to the selected kinds and that + multiple causes remain discoverable through `errors.Is`/`errors.As`. + Diagnostic records keep their order and existing presentation responsibility. + +**Validation:** Run focused smoke outcome tests and the full ckprompt suite. +Each assertion must detect CommandKit presentation/coordination/delivery defects; +provider smoke-test correctness belongs upstream. + +**Complete when:** realistic smoke failures preserve their reports, native error +identity, and delivery outcomes without a parallel diagnostic test suite. + +## Stage 15: Demonstrate the new interfaces in the maintained consumer + +**Primary files:** `integrations/ckprompt/examples/composed`, its README, +synthetic configuration, and tests. + +1. Extend the already migrated small consumer with the updated catalog callback + API and explicit `WithSmokeTesting` wiring. Keep configuration scopes, + existing requirements operations, campaign selection/cache, and session + restore intact. +2. Demonstrate backend/namespace/collection inventory and native namespace + selection with the smallest useful configuration. A small synthetic + collection may be used where useful; do not turn this into a collections + composition tutorial or catalog migration project. +3. Reuse shared state for engine/application acquisition where natural in this + example. This is consumer behavior, not a new library caching requirement. +4. Show nil-builder smoke wiring and explain optional typed request construction + with a minimal snippet or focused test. A builder starts from the native + seed and returns the chosen native request; no merge policy is added. +5. Keep executed consumer checks offline. Use a small injected public + `promptkit.LLMClient` double for inference when exercising the native helper; + HTTP diagnostics can retain native unsupported/not-applicable observations + when no probe is configured. Do not recreate native private expected + responses or assert provider diagnostic correctness to make a demo green. +6. Update documented commands for ID-only inspection, optional versions, discovery, + and `test KIND`/`test all`. State any example-specific fixture/client setup + plainly. Check metadata/requirements commands leave the injected client + unused; explicit smoke commands use their selected native path. + +**Validation:** Run composed-consumer tests and representative documented offline +commands. Assert wiring and adaptation; an intentionally returned native +diagnostic error is a documented example outcome, not a reason to redefine the +native API's success criteria. + +**Complete when:** the consumer demonstrates the new interfaces with little +application plumbing and no model-service prerequisite. + +## Stage 16: Reconcile dependency graphs and notices + +**Primary files:** all three module manifests/sums and attribution documents. + +1. Tidy/prepare dependencies with each module's own graph, using disposable + module files and version-specific replacements only for unpublished + CommandKit prerequisites where needed. Keep actual released upstream + dependencies selected; do not use sibling upstream replacements. Transfer + resulting dependency/sum edits back to the owning manifests without copying + temporary replacements or changing the declared CommandKit prerequisites. +2. Remove obsolete bundled backend-catalog requirements/sums and their notices + when absent from the actual selected ckprompt graph. Retain other indirect + requirements only as generated by the module tools. +3. Update notices for every affected selected graph, including ReleaseKit + selection through the local core. Do not blindly copy the root tool version + into each integration's notices; verify its effective graph. +4. Compare applicable copyright/license/notice material and pin upstream source + links to the selected release revisions. Reuse unchanged standard license + texts and preserve each module's existing local grant/material boundaries. +5. Keep checked-in CommandKit prerequisite versions unchanged until actual + release preparation selects and publishes successors. Do not fabricate + future versions/checksums or use temporary replacements as release metadata. + +**Validation:** Inspect independent `go list -m all` output and changed +manifests/sums/notices. Confirm ConfigKit v0.8.0 in both integrations, PromptKit +v0.16.0 in ckprompt, and no optional integration dependency in core. + +**Complete when:** selected graphs, real checksums, removed catalog dependencies, +and owning attribution entries agree. + +## Stage 17: Update canonical documentation and planning references + +**Primary files:** GoDoc, module READMEs, `docs/cli.md`, +`docs/consumers/guide.md`, `docs/development.md`, `docs/internal/overview.md`, +and affected roadmap references. + +1. Document the new callback requests, helper signatures, optional capabilities, + native defaults, builder authority, error-bearing reports, and aggregate + lifetimes in their owning GoDoc. Replace stale five/six-capability statements + with the actual eight `FromEngine` callbacks and two explicit additions. +2. Update the CLI reference for source evidence, ID-only selection, optional + `version` omission, all five catalogs and filters, and the complete smoke + vocabulary/bindings/report/outcome behavior. Include concrete aggregate + envelope and native projection examples from the implemented renderer. +3. Update consumer guidance, module summaries, internal inventory, and developer + example commands. Scope existing metadata-only/no-provider-call descriptions + to those operations; smoke is explicitly invoked native behavior. +4. Link to the adopted upstream contracts for native configuration, selection, + and diagnostic meanings. Use neutral field descriptions and avoid warnings, + extra promises, or independent restatements of native algorithms. +5. Reconcile the selected native smoke capability with `deferred.md`, preserving + unrelated future proposals. Record its implemented boundary rather than + treating all credential/runtime diagnostic ideas as delivered. +6. Repair references from completed `promptkit-validation.md` and `remediation.md` + to the previous implementation plan using its pinned historical link above. + Those records remain historical; do not update their old API examples to + describe the new feature. +7. Keep accepted ADRs and policy boundaries intact unless a concrete conflict + emerges. Do not create ADRs for report-key or private helper choices. Keep + historical release notes unchanged; document release impact under the + existing pre-v1 policy, with exact release versions chosen during preparation. + +**Validation:** Check Go examples and CLI commands against actual declarations, +local links/fragments, Markdown whitespace, stale selector/callback-count +claims, and accidental consumer mandates. No new documentation checker code +is required. + +**Complete when:** current contracts describe implemented behavior under their +canonical owners and historical references remain correctly scoped. + +## Stage 18: Verify the complete target and finish + +1. Format all changed Go files and inspect the full diff for unrelated changes, + local replacements, generated caches, fabricated sums, or accidental public + exports. Keep ignored `go.work`/`go.work.sum` and `.releasekit/` local. +2. Run all affected module suites in the local workspace: ```sh GOTOOLCHAIN=local go test -count=1 ./... @@ -484,60 +698,54 @@ Markdown links and anchors and Markdown whitespace checks passed. (cd integrations/ckprompt && GOTOOLCHAIN=local go test -count=1 ./...) ``` - Root `./...` does not traverse nested modules. These ordinary suites do not - authorize a release publication exercise or live model service tests. -3. Separately verify each module with `GOWORK=off`, `GOTOOLCHAIN=local`, and - `-mod=readonly`. For unpublished CommandKit prerequisites, create temporary - absolute-path copies of each affected module's `go.mod` and `go.sum`, keeping - paired names such as `ckprompt.mod` and `ckprompt.sum`. Run from that module's - real directory with `-modfile=/absolute/temp/path/ckprompt.mod`. + Root `./...` does not traverse nested modules. Reuse unchanged successful + evidence where appropriate; none of these commands invokes publication. +3. Verify independent readonly graphs with `GOWORK=off` and + `GOTOOLCHAIN=local`. For unpublished CommandKit prerequisites, create + temporary absolute-path `.mod`/`.sum` pairs copied from the owning module. + Replace only the required core version with the local root for ckconfig, + and only the required core/ckconfig versions for ckprompt. +4. Prepare needed sums in those temporary files, then run + `go test -mod=readonly -count=1 ./...` from each actual module directory with + the applicable `-modfile=/absolute/path/module.mod`. Root uses its actual + manifest without optional-library replacements. Hash temporary module/sum + files before/after readonly checks and confirm they stay unchanged. + ConfigKit, PromptKit, and ReleaseKit remain real released modules. +5. Inspect `go list -m all` and `go list -deps -test ./...` using those same + isolated graphs. Prove core has no optional integration libraries, + ckconfig has no PromptKit/ckprompt dependency, and ckprompt selects the + intended adopted releases. A workspace pass alone is insufficient. +6. Review the target checklist below against actual source and test evidence. + Run prose/link checks and review maintained examples alongside their actual + command declarations. Do not introduce mandatory live probes, race/coverage + thresholds, benchmark gates, or platform matrices. +7. Mark stages complete only with actual evidence, update the roadmap's status, + and identify any genuine remaining limitation accurately. Retain planning + records until cleanup is requested. Commit the completed sprint's remaining + nonempty work, inspect status, and report the commits and validation. + Do not tag, push, or publish a release. - - Core: use its actual manifest; no optional-library replacements. - - ckconfig: replace only its required core version with the current root. - - ckprompt: replace only its required core and ckconfig versions with their - current local directories. - - Use version-specific replacements for the versions in the manifests. - PromptKit and ConfigKit remain real released dependencies. Temporary - replacements are validation scaffolding, never committed metadata. - - Prepare any needed cache/checksums in the temporary copies, then record - their hashes before running readonly tests. Verify those files are unchanged - afterward. A workspace-only pass does not establish isolated resolution. +**Complete when:** every target below is implemented and evidenced, documentation +and dependency metadata agree, and the workspace is clean. - In each module, use `go test -mod=readonly -count=1 ./...` with the applicable - `-modfile` and environment above. Inspect `go list -m all` and - `go list -deps -test ./...` with the same isolated manifest: core has no optional - integration dependency; ckconfig has no PromptKit/ckprompt dependency; - ckprompt selects released PromptKit v0.15.0. Do not change checked-in - prerequisite versions merely to make isolated checks easier. Remove temporary - module files after retaining the relevant validation evidence. -4. Review the Stage 7 commands and canonical docs together. Check that the - nil-builder path and typed builder are both covered, show still permits - partial discovery, errors preserve native categories, and only the agreed - YAML confirmation is emitted on validation success. -5. Run relevant prose whitespace/link checks, including staged documentation. - Confirm the integration attribution matches the selected released dependency. - No new coverage threshold, benchmark, platform matrix, release gate, or - threat scope is introduced by this plan. -6. Mark completed stages with actual evidence, update the feature roadmap's - implementation status, and record any genuine remaining limitation accurately. - Commit outstanding sprint changes using a concise plain-English message, - inspect status afterward, and report the final commit(s) and validation. - Retain planning documents until their cleanup is requested. +## Target verification checklist -**Complete when:** every accepted roadmap capability is implemented, all -applicable evidence above passes, public documentation and module metadata are -aligned, and the workspace is clean. No unresolved product or API decisions -were identified in preparing this plan. +| Target | Primary stages | Completion evidence | +| --- | --- | --- | +| ReleaseKit v0.4.2, unchanged publication model and Go selections | 1, 16, 18 | Selected root tool graph, launcher boundary tests, factual docs/notices | +| ConfigKit v0.8.0 in both integrations | 2, 16, 18 | Independent module graphs and released checksums | +| New source evidence in text/YAML | 3 | Controlled-record projection tests; unchanged existing source fields | +| ID-only PromptKit v0.16.0 API and explicit configuration | 4–5 | Removed selectors, migrated native fixtures and consumer, boundary tests | +| Optional `version` omission/empty preservation | 4–5, 7, 10 | Semantic report assertions across affected reports | +| Independent backend/namespace/collection catalogs and native filters | 6–8 | Public callbacks, command capture, native forwarding, availability and YAML | +| Optional concrete smoke callback/helper and full agreed bindings | 9, 11, 13 | Seed/builder/native forwarding, pointer presence, lifecycle evidence | +| Faithful smoke reports, partial results, supported error identity | 9–14 | Synthetic projections and assembled outcomes/delivery tests | +| Ordered `test all`, continuation, cancellation, per-kind builders | 12–14 | Controlled aggregate call sequence, reports, and joined causes | +| Small maintained consumer and current canonical documentation | 15, 17 | Offline consumer evidence, reviewed commands and local links | +| No reverse optional dependencies, obsolete catalog graph, or local upstream replacements | 16, 18 | Independent manifests/module/test-import listings and notices | +| Upstream testing ownership respected | All testing stages | Assertions address CommandKit interfaces and coordination, not native domain correctness | -**Completed:** 2026-10-12. All three workspace suites passed, followed by all -three isolated `GOWORK=off`, `-mod=readonly` module suites. Module and test -dependency listings confirm the core and ckconfig boundaries, and ckprompt -selects released PromptKit v0.15.0. Temporary ckconfig and ckprompt module files -used only version-specific local replacements for unpublished CommandKit -prerequisites; their module and sum hashes were unchanged by readonly checks. -Both successful composed validation commands emitted only the requested -`prompt_id` and `valid: true`; the missing-topic command failed operationally at -native required-artifact validation. The complete ckprompt suite also passed -the nil-builder, typed-builder, partial-discovery, and native-error coverage. -The selected PromptKit attribution matches v0.15.0, changed documentation links -and whitespace checks passed, and no unrelated or generated changes remain. +No product or API question requires a separate decision before these stages +can begin. Concrete presentation and wiring choices above stay within the +accepted roadmap; implementation should not elevate incidental details into +additional guarantees. diff --git a/docs/roadmap/upgrades.md b/docs/roadmap/upgrades.md index a7732f8..74cb484 100644 --- a/docs/roadmap/upgrades.md +++ b/docs/roadmap/upgrades.md @@ -3,7 +3,7 @@ Status: adoption roadmap; implementation has not started. The release targets, adoption order, and OD-1 through OD-4 are accepted. Smoke testing is included in the current scope. This document defines the desired end state and required -work; a separate implementation plan will sequence coding tasks. +work; the [implementation plan](implementation.md) sequences coding tasks. ## Purpose and authority @@ -43,7 +43,8 @@ outcomes. ckconfig owns the configuration family. ckprompt currently supplies prompt/profile catalogs, named inspection, requirements discovery, and concrete request validation; its engine configuration scope is composed through ckconfig. -The completed requirements roadmap, implementation plan, and remediation record +The completed requirements roadmap and remediation record, together with their +[original implementation plan](https://gitea.maximumdirect.net/eric/CommandKit/src/commit/38b49f29fb3a8f22ff02528d2a0ed413e5c6ab1e/docs/roadmap/implementation.md), remain historical evidence for the delivered baseline. This roadmap describes new work and does not restart those completed assignments. @@ -58,18 +59,13 @@ Reviewed upstream references: All three releases retain Go 1.26.0 as their consumer minimum. The adoption does not require changing CommandKit's Go minimum or selected release toolchain. -## Adoption order and delivery boundaries +## Dependency and delivery boundaries -| Order | Adoption | Reason | -| --- | --- | --- | -| First | ReleaseKit v0.4.2 | A small, independent maintainer-tool update establishes the selected tool before integration migration. | -| Next | ConfigKit v0.8.0, including richer source inspection | Supplies the prerequisite for PromptKit v0.16.0 and exposes useful native evidence through ckconfig. | -| Then | PromptKit v0.16.0 API/configuration migration | Removes obsolete version selectors and bundled-catalog assumptions across ckprompt. | - -Expanded PromptKit discovery and explicitly invoked smoke testing are included -after its base migration. These are product/dependency relationships, not a staged -implementation plan or a requirement for separately releasable intermediate -commits. ConfigKit and PromptKit can be handled in one coordinated sprint. +The target includes all three upgrades, richer configuration source inspection, +expanded PromptKit discovery, and explicitly invoked smoke testing. The +[implementation plan](implementation.md) owns coding order and stage boundaries. +These changes can be delivered in one coordinated sprint without separately +releasable intermediate commits. ReleaseKit has no runtime ordering dependency on the other two. ConfigKit must be adopted before, or atomically with, PromptKit: Go module selection would @@ -201,7 +197,7 @@ its native scope. Migration guidance should link to the upstream ### Expanded operator discovery -After the base migration, extend the existing optional family with: +The optional family exposes these additional catalogs: | Operation | Native capability | | --- | --- |