Files
commandkit/docs/roadmap/implementation.md

44 KiB
Raw Blame History

Dependency upgrades, discovery, and smoke testing implementation plan

Status: Stages 1–2 complete; Stage 3 is next.

Authority and baseline

Implement the accepted upgrade roadmap 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, accepted ADRs, 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. That feature is baseline behavior to migrate, not an unfinished assignment.

Working rules

  • Start with development guidance 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. 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.
  • 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:

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.

Completed: 2026-10-17. The root selects ReleaseKit v0.4.2 with Go-generated module checksums; attribution, release policy, and pinned runbook references match upstream commit 7d033c5ca1c95aec7db9690293638a0a1ac887b8. Upstream COPYRIGHT and LICENSE were unchanged. Launcher argument/delegation tests and GOWORK=off GOTOOLCHAIN=local go test ./... passed. Profiles and the existing source-only launcher contract required no changes.

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.

Completed: 2026-10-17. Both integration modules select ConfigKit v0.8.0 with generated checksums, and ckprompt continues to select PromptKit v0.15.0. The source record usage review found no unkeyed literals, equality, or map-key uses requiring changes; the existing adapters preserve native records. The ckconfig suite passed and ckprompt packages and tests compiled with no tests run. Upstream COPYRIGHT and LICENSE were unchanged.

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:

    GOTOOLCHAIN=local go test -count=1 ./...
    (cd integrations/ckconfig && GOTOOLCHAIN=local go test -count=1 ./...)
    (cd integrations/ckprompt && GOTOOLCHAIN=local go test -count=1 ./...)
    

    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.

Complete when: every target below is implemented and evidenced, documentation and dependency metadata agree, and the workspace is clean.

Target verification checklist

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

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.