From 89af2a128175e4c84301833850232f5bc0158306 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 17 Oct 2026 05:26:42 +0000 Subject: [PATCH] Plan configuration collections implementation --- docs/roadmap/configuration-collections.md | 57 +- docs/roadmap/implementation.md | 1431 ++++++++++----------- 2 files changed, 698 insertions(+), 790 deletions(-) diff --git a/docs/roadmap/configuration-collections.md b/docs/roadmap/configuration-collections.md index 12da2b3..658b27e 100644 --- a/docs/roadmap/configuration-collections.md +++ b/docs/roadmap/configuration-collections.md @@ -2,8 +2,9 @@ Status: accepted feature roadmap; not implemented in PromptKit. This document consolidates the namespace roadmap and selected collection proposal 3. The -configuration and namespace design decisions are settled; public API details -and staged implementation planning remain delivery work. +configuration and namespace design decisions are settled. The companion +[implementation plan](implementation.md) defines concrete API delivery choices +and the staged work needed to reach this target state. ## Purpose @@ -25,11 +26,10 @@ and provenance guarantees. ## Prerequisite: Adopt ConfigKit v0.8.0 -Adopt released ConfigKit **v0.8.0** before implementing the new collection schema -and loading APIs. PromptKit currently selects v0.7.1. Update the module dependency -and checksums, review affected public API compatibility and attribution, and -verify the existing ConfigKit integration as the prerequisite implementation -unit. Do not use a committed local filesystem replacement for adoption. +The target selects released ConfigKit **v0.8.0** for the collection schema and +loading APIs. PromptKit currently selects v0.7.1. Dependency adoption and its +verification belong to the [implementation plan](implementation.md); local +filesystem replacements are not part of the distributed module. The v0.8.0 tag was reviewed at `137769f` on 2026-10-17. It supplies input placement, relative import destinations, and shared source-version checks needed @@ -164,7 +164,8 @@ below. Provide a lightweight, immutable view over an existing engine with independent prompt, profile, and backend scopes. The following sketch illustrates the -accepted shape; method/type names and final signatures remain provisional: +accepted shape; concrete declarations are specified in the +[implementation plan](implementation.md): ```go weather, err := engine.WithNamespaces(Namespaces{ @@ -266,7 +267,7 @@ listings for the supported resource types, adding a backend inventory surface as part of this work if needed. Namespace filtering is an explicit option in the library listing API, not a consumer-side filtering helper. Preserve unfiltered engine listing behavior, with the accepted removal of prompt-version identity -and selection; the exact Go option shape remains to be specified. +and selection. The companion implementation plan defines the Go filter shape. | Selection | Listing behavior | | --- | --- | @@ -655,7 +656,8 @@ Derive collection inventory from the final `collections` mapping: namespace plus optional effective `release_version`, sorted and detached from the captured engine. Metadata-only and resource-only entries can both appear. Root unqualified resources do not invent a named collection; resource-based namespace enumeration -remains separate. Exact exported inventory types remain API design work. +remains separate. The companion implementation plan defines exported inventory +types. An inventory describes effective configuration, not immutable package identity, historical source ownership, or proof of unchanged published contents. Operator @@ -724,20 +726,16 @@ Explicit source destinations, direct fragments, programmatic sources, and consumer-selected precedence remain supported in the design. Deferred features can be reconsidered for concrete needs; none blocks implementation. -## Delivery And Validation +## Target Acceptance -The next work is a staged implementation plan grounded in these accepted -contracts. Its first prerequisite is [ConfigKit v0.8.0 adoption](#prerequisite-adopt-configkit-v080). -Then cover the collection schema and final configuration adapter, catalog and -built-in removal, prompt-version API removal, immutable scoped views, integrated -filtering, and collection inventory. Build qualified runtime indexes after -ConfigKit handoff. Select exact helper signatures, listing options, and metadata -representations using representative consumer examples. - -Plan focused offline validation under the [testing policy](../policy/testing.md). -Update GoDoc, the format reference, consumer guidance, affected release policy, -and internal documentation when behavior lands. Retire this roadmap after the -work is complete. This outline is not yet the staged implementation plan. +The target includes the collection schema and final configuration adapter, +catalog and built-in removal, ID-only prompt selection, immutable scoped views, +integrated filtering, and collection inventory. Runtime indexes use full +identities after ConfigKit handoff. Current contracts and consumer migration +guidance describe the implemented behavior when it lands. The +[implementation plan](implementation.md) owns sequencing, concrete public shapes, +documentation tasks, and focused offline validation under the +[testing policy](../policy/testing.md). ### Namespace And Consumer Acceptance @@ -802,14 +800,13 @@ replacement, inheritance limits, header consumption, and final identity validati boundaries. The latter review informed the decision to retain mappings. These checks establish upstream behavior, not an implemented PromptKit feature. -## Remaining Delivery Details +## Delivery Reference -No substantive design question remains before staged implementation planning. -ConfigKit v0.8.0 is the selected prerequisite, not an unresolved release choice. -Finalize public helper signatures, inventory and optional-label representations, -identifier migration mappings, and concrete consumer migration examples in the -plan and implementation. Do not reopen settled workflows or add speculative -options merely to complete API shapes. +No substantive design question remains. ConfigKit v0.8.0 is the selected +dependency. The [implementation plan](implementation.md) specifies helper +signatures, inventory and optional-label representations, identifier migration +mappings, and consumer migration work. Its delivery choices implement these +accepted contracts without adding speculative options or reopening workflows. ## Consolidation And Retired Alternatives diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 8f31f0d..c8b115a 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,778 +1,689 @@ -# Smoke Test Diagnostics Implementation Plan +# Configuration Collections Implementation Plan -Status: complete; catalog publication remains separate release preparation. +Status: ready for implementation; no feature changes are implemented by this plan. -Implement the accepted [feature roadmap](smoke-tests.md). This document owns the -implementation sequence; the feature roadmap owns the requested API, factual -reporting semantics, selection rules, and scope. Each numbered stage is a single -bounded prompt for a Luna coding agent. Execute stages in order within one sprint. -There are no intermediate human-review, external-publication, or live-provider -gates. Focused automated validation and local commits are ordinary development -steps, not pauses awaiting approval. +Implement the accepted [feature roadmap](configuration-collections.md). That +document owns intent, scope, and selected policy; this document owns API delivery +choices and the ordered implementation steps. Each numbered stage is sized as +one prompt for a Luna coding agent. Complete stages in order. Foundation and +migration stages are parts of one refactor, not separately publishable releases. ## Baseline And Working Rules -The reviewed PromptKit baseline is `c8f9a4def9f84301bf534a331320ea9fb798ac24`. -It selects both `/v3` catalogs at `v3.20260930.0` and ConfigKit at `v0.7.1`. -The adjacent checkouts are: +Reviewed PromptKit baseline: `683689a4f89d0fea6a8e0c6faf5830414adf9c7b`. +It selects ConfigKit `v0.7.1`, both `/v3` provider catalogs at +`v3.20261013.0`, and the completed smoke-test implementation and remediations. +The existing implementation plan described that completed work; Git retains it. +This plan replaces it without reopening the smoke-test design. -- `../promptkit-backend-openrouter`, reviewed at - `f17d208cb7ad1fb043cda2266cd3011d11b40aa0`; -- `../promptkit-backend-rakestrawhome`, reviewed at - `993443d88c451901f4c917fa00c204fd3b54d28d`. +ConfigKit `v0.8.0` resolves to commit +`137769f3f18a370c68444242fb5d88e620e307e5` (the annotated tag object is distinct). +Its released public contracts in `docs/config.md`, release notes, and ADRs +0011–0014 supply the required placement and shared version-check behavior. +The adjacent checkout is a reference, not a committed build dependency. -Recheck repository status before editing and preserve unrelated work. Begin with -[development orientation](../development.md), then the applicable -[agent](../policy/agents.md), [architecture](../policy/architecture.md), +Before each stage, inspect status, preserve unrelated work, read the owning +implementation/tests, and follow [development orientation](../development.md). +Apply the [agent](../policy/agents.md), [architecture](../policy/architecture.md), [testing](../policy/testing.md), [documentation](../policy/documentation.md), -[OSS](../policy/oss.md), and [release](../policy/release.md) policies. Read each -catalog's own instructions and release procedure before its stages. Reuse -unchanged policy readings during the sprint. +[OSS](../policy/oss.md), and relevant [release](../policy/release.md) policies. +Use the repository's code-discovery instructions. Reuse unchanged readings. +Update affected GoDoc and canonical contracts as each behavior lands; Stage 17 +is a consistency pass, not permission to leave current documentation stale. -Read focused internal documents and owning tests before modifying a component. -Use existing code-discovery guidance. Stage and commit each completed, nonempty -unit with a short plain-English message after proportionate checks and staged-diff -review. Record stage completion and relevant validation here. Catalog stages -commit in their own repositories; PromptKit records their tag and full commit -identities here. Do not push any repository or publish a PromptKit release during -this implementation sprint. +Record completion and validation beneath the stage, then commit each completed, +nonempty unit with a short plain-English message. These stages change PromptKit; +external collection publishing is separate work. Do not push, tag, release, or +introduce committed workspace/replacement files. The sprint requires neither +publication of a new catalog nor a live provider. +Dependency acquisition is setup, separate from offline behavioral validation. -Only final effective ConfigKit values are interpreted or validated by PromptKit, -per [ADR 0001](../adr/0001-configuration-boundary.md). Do not inspect raw catalog -documents or source history to enforce domain validity, even in PromptKit tests. -The catalog repositories may test the assets they themselves own. Operator -inspection continues to delegate to ConfigKit. +Maintain [ADR 0001](../adr/0001-configuration-boundary.md): ConfigKit owns source +processing, composition, inheritance, and header checking through its configured +version callback. PromptKit interprets final effective values and their resource +contexts. Do not inspect contributions or source history to enforce domain +validity, including in tests. Explicit operator inspection remains available. -Keep existing `Run`, `Prepare`, `ValidateRequest`, repair, observation, and client -contracts unchanged. Add no application CLI, readiness verdict, custom test -criteria, batch operation, live release gate, or new public transport injection -option. Do not add catalog exclusion controls absent from the current API. +Preserve execution, retry/repair, credentials, appended messages, capacity, +observations, cancellation, and prepared-handle semantics except for the accepted +identity/version changes. Introduce no installer, implicit discovery, new +provider protocol, cross-collection inheritance resolver, compatibility alias +bundle, live reload, or additional release gate. -## Implementation Decisions +## Delivery Decisions -These decisions resolve the feature roadmap's delivery details. Internal names -below identify a concrete implementation path, not additional public contracts. +These names and signatures settle delivery details left by the feature roadmap. +Private helper names below are implementation guidance, not public invariants. -### Configuration And Catalog Assets +### Final Configuration And Runtime Identity -Add optional `smoke_tests` to final backend definitions: +Use a typed root document with optional `version`, root `backends`, `profiles`, +and `prompts`, and `collections`. Each collection body has optional +`release_version` and the same three resource mappings. Root and collection +resource maps are keyed by local ID; `prompts` maps directly to definitions, +not another version map. Keep ordinary strict ConfigKit decoding and existing +definition rules. Collection bodies are mappings; an empty body is useful. -```yaml -backends: - openrouter: - smoke_tests: - default_profile: promptkit-openrouter-standard - authentication: - kind: openrouter_key - rakestrawhome: - smoke_tests: - default_profile: rakestrawhome-gemma-4-31b - authentication: - kind: none +Represent source-root `version`, collection `release_version`, and prompt +`version` with `*string` in the typed document. Configure +`Definition.Version.Path = configkit.Keys("version")` and +`SourceVersionModeIfPresent`. The checker accepts absence, accepts exact text +`1` from a string or strict decimal integer, and rejects explicit null or other +texts with a safe ConfigKit diagnostic. ConfigKit owns type checking and +non-main header consumption. Do not synthesize a main input or declaration. +Collection release and prompt labels are opaque strings: nil means absent/null, +and a non-nil empty string remains explicitly declared. Do not trim, order, +interpret as SemVer, or require these labels. + +Keep the retained ConfigKit result in its authored effective shape. Refactor +configuration helpers to receive the effective resource base path rather than +reconstructing it from a runtime ID. Visit root and collection mappings with +their actual paths; after handoff, index each resource under its full public ID. +Do not flatten/re-key the ConfigKit result or make a second load. Presence, +normalization records, content-file origins, secret classification, explanations, +and diffs must keep the effective paths, including `collections/`. + +Create shared private identity helpers under `internal/domain`. Follow the +roadmap's exact grammar: a nonblank unqualified ID has no slash; a qualified +reference has exactly one slash and two nonempty components. A configured local +key is nonblank and slash-free. A collection namespace is nonblank and +slash-free, using the same syntax as a nonempty scope. Preserve spelling, +including otherwise permitted whitespace, dots, case, and punctuation. Add no +other character whitelist. Never apply this grammar to models, paths, URLs, +artifact/input names, session IDs, or descriptive labels. + +Validate final configured resource keys and effective PromptKit references. +Retain existing existence/readiness timing: for example, profile backend +existence is checked as today, but an unselected backend diagnostic default is +not made eagerly resolvable. ConfigKit interprets `extends` as a sibling key, +not a PromptKit qualified reference. PromptKit does not validate or reinterpret +consumed inheritance directives. + +### Prompt Selection And Optional Labels + +Remove `PromptVersion` from public/internal `RunRequest`, +`RequirementInspectionRequest`, and `SmokeTestRequest`. `ValidateRequest`, +`Prepare`, and `PrepareExecution` continue to use `RunRequest`. +Change `InspectPrompt` to: + +```go +func (e *Engine) InspectPrompt(ctx context.Context, promptID string) (*PromptInspection, error) ``` -Both catalogs omit a separate reachability endpoint so ordinary endpoint overrides -remain effective. Caller definitions may set `reachability.endpoint` or -`authentication.endpoint` to an absolute diagnostic destination. Authentication -otherwise joins `key` to the effective base; reachability otherwise uses that base. - -The public convenience surface adds `SmokeTests *BackendSmokeTestConfig` to -`BackendConfig`, with: - -- `BackendSmokeTestConfig`: `DefaultProfile *string`, - `Reachability *ReachabilityProbeConfig`, - `Authentication *AuthenticationProbeConfig`; -- `ReachabilityProbeConfig`: `Endpoint *string`; -- `AuthenticationProbeConfig`: `Kind *string`, `Endpoint *string`. - -`BackendSource` omits nil convenience fields, as it does today. Explicit nulls -remain expressible with ordinary ConfigKit mappings/YAML. In final values, -omitted/null `smoke_tests` disables its defaults and authentication declaration; -omitted/null `default_profile` means no inference default; omitted/null -`reachability` or its endpoint means generic reachability at the effective base; -omitted/null `authentication` means unsupported authentication; a non-null -authentication object requires `kind`. Recognize `none` and `openrouter_key`. -Normalize surrounding whitespace/case for adapter kinds and record normalization -through the existing ConfigKit resolution boundary. Preserve profile IDs exactly; -a supplied default-profile string must not be blank. Resolve its existence only -when that default is selected, not eagerly at engine construction. - -Diagnostic endpoint strings are trimmed and parsed as absolute HTTP(S) URLs with -a host. Use standard URL/request validation, allowing paths and queries; do not -reuse the base-endpoint validator's query restriction for these full URLs. Null -means fallback, whereas an explicit blank endpoint is invalid. Retain existing -base-endpoint rules for ordinary target overrides. Reachability sends no -Authorization header or URL user credentials. Public endpoint fields omit URL -user information; other URL components and provider settings remain potentially -sensitive operator data, as specified in the feature roadmap. - -Preserve the existing `/v3` catalog asset format: do not place new fields under -the existing `Root` where older strict loaders would reject them. In each module, -add `smoke-tests/backend.yml` and the additive exported constant -`SmokeTestsRoot = "smoke-tests"`; extend `FS()` embedding to include that root. -Keep `Root = "catalog"` and its existing assets unchanged. New PromptKit explicitly -selects both roots through `internal/catalog`; diagnostic data remains -catalog-owned. This is a small opt-in asset surface, not another runtime library -or a PromptKit-owned metadata underlay. - -### Private Fixtures And Evaluation - -Put fixed inference messages and a self-contained embedded schema in -`internal/usecase` alongside diagnostic orchestration. Use an ordinary user -message requesting the exact token `PROMPTKIT_OK` for text inference. Structured -inference requests `{"status":"ok"}` with an object schema requiring that single -string property with `const: "ok"` and `additionalProperties: false`. -Use native schema name `promptkit_smoke`, strict mode, and the existing structured -output serializer. These literal choices are private and may change; do not -duplicate them across public tests or documentation. - -Use `internal/validate.NewFSValidator` with this private schema filesystem, not -the application's schema source. Prepare validation once per diagnostic call and -reuse its schema document for native output. Use existing JSON and schema -validation mechanisms for distinct `ValidJSON` and `SchemaMatched` facts. Do not -repair content. Text matching trims whitespace only. JSON/schema failures use -`ExecutionFailureValidation`; an unexpected text answer is expressed by the -text facts without inventing a domain-validity verdict. - -### Shared Execution And Evidence - -Keep source-neutral diagnostic values under `internal/domain`. Add a -`usecase.SmokeTester` assembled with the existing runner's captured selection -collaborators, the same generation coordinator, admission manager, and a narrow -built-in HTTP probe collaborator. Share existing private selection and override -helpers within `internal/usecase`; do not implement diagnostics by calling `Run` -or `Prepare`, and do not render an application's prompt. - -Add a per-invocation internal evidence path to `internal/llm` and -`internal/generation`. A diagnostic `GenerateWithEvidence` entry point and -ordinary `Generate` share the same private generation implementation. Ordinary -calls need not allocate diagnostic records. Evidence retains dispatch state, -final observed destination, HTTP status, credential presence, decoded-response -availability, timings, and presence-aware usage before existing cancellation -checks can discard a result. Private response content exists only long enough -for local evaluation and is not copied into reports. - -Observe HTTP requests with an invocation-local wrapper around the selected -client's RoundTripper, on a shallow client copy. Preserve its timeout, redirects, -cookie jar, and underlying transport; do not mutate a caller's client or forward -credentials specially. A nil transport uses `http.DefaultTransport`. Record only -the most recent observed request and response, resetting destination-specific -response evidence on each new hop. This reports what PromptKit can observe at -its boundary, not wire transmission or any hidden dispatch inside a custom -transport. Do not retain headers, credentials, raw bodies, or a redirect trace. - -Reuse the coordinator's failure classification and extract its existing -presence-aware usage aggregation into a small internal reusable accumulator if -needed. Do not duplicate that arithmetic or expand public `ExecutionEvent`. -Mask enclosing execution observation with `observation.WithoutExecutionState` -so diagnostic traffic does not become an application's ordinary execution events. - -### Result And Error Decisions - -Use the request/report declarations and reason constants in the feature roadmap -without adding status/severity or a stable JSON guarantee. Reports own their -pointer values, attempt slices, effective-setting maps, and usage values. Copy -mutable request overrides using existing ownership helpers before handing them -to collaborators. Apply existing request credential redaction to formatting and -exclude `APIKey` from JSON. Do not store request credentials on an engine. - -Invalid selections, kinds, overrides, or negative retry settings are public Go -errors before dispatch. Validate numeric/settings bounds even when a supplied -setting is unused by an HTTP operation; do not require a model for HTTP probes. -Concluded diagnostic execution findings become reports, not raw provider errors. -Required inference credentials missing locally produce -`required_credential_missing` and `invalid_request`. HTTP authentication may -dispatch without credentials even if inference would require them. - -Reachability records any observed HTTP response as reachable and received; -non-2xx status alone is not failure of this probe. Authentication records -documented 401 rejection and recognized 200 acceptance. For its 200 recognition, -require one JSON object with a `data` object, string `label`, Boolean -`is_free_tier`, and numeric `usage`; tolerate unrelated fields and ignore account -limits. These are a minimal identifying subset of the provider's documented -[current-key response](https://github.com/OpenRouterTeam/docs/blob/main/api_reference/limits.mdx#checking-your-limits), -not a validation of the full account document. An unrecognized 200 yields the -accepted reason and `malformed_response`; other statuses retain acceptance nil -and use ordinary provider-status classification. Never infer acceptance from -arbitrary provider text. - -For inference, generation/transport failures retain their existing classifications. -Set content facts only when evaluation actually occurs. Preserve decoded -generation and usage evidence even when subsequent caller cancellation interrupts -evaluation. A malformed HTTP envelope still counts as an observed response. -An injected client establishes response availability and generation facts, not -HTTP reachability, destinations, status, or upstream credential supply. - -Use the configured client timeout and selected target timeout, as the existing -built-in client does. When the outer caller context remains active, an elapsed -request timeout concludes a report with `deadline` and nil Go error. If caller -cancellation/deadline interrupts the diagnostic, return the partial report with -`ctx.Err()` identity, `Completed=false`, and corresponding failure. Check context -before dispatch and between phases; synchronous injected code must return before -PromptKit can observe cancellation. Preserve a diagnostic already completed -before later cancellation; do not promise new behavior for preparation APIs. - -Report-level facts come from the last dispatched attempt, then its local -evaluation. A later undispatched wait cannot erase them. An interrupted backoff -adds elapsed retry delay, not an attempt. Total timing includes orchestration; -phase sums need not equal wall time. Request time includes transport/body/envelope -work but excludes capacity wait, retry delay, and generated-content evaluation. -Absent phases stay nil; performed work can measure zero. - -Internal fixture loading/compilation, request construction, or assembly faults -that prevent meaningful diagnostic execution may return a content-free Go error -through the existing facade boundary. Do not recover arbitrary panics or promise -that every internal fault becomes a report. Do not expose raw provider or injected -error text in a diagnostic report or its operational-error return. - -## Stage 1: Add Internal Diagnostic Values - -Scope: `internal/domain`, with focused ownership helpers only. - -1. Add request, report, target, facts, timing, attempt, kind, and reason values - corresponding to the feature roadmap. Reuse existing execution settings, - failure kinds, and observed usage types. -2. Add source-neutral backend smoke-test metadata values to `domain.Backend`. - Keep ConfigKit and HTTP transport types out of domain values. -3. Implement copying needed for nested optional metadata, report values, and - provider maps with existing JSON-value helpers. Separate private decoded - response evidence from report values so conversion cannot expose content. - -Validate: `go test ./internal/domain ./internal/backend`. Add ownership tests -only for mutable structures whose accidental sharing would affect calls. -No public `SmokeTest` method or temporary not-implemented API is introduced yet. - -**Completed: 2026-10-13.** - -## Stage 2: Load Final Backend Diagnostic Metadata - -Scope: `internal/configuration`, `internal/backend`, and `backends.go`. - -1. Extend the final typed configuration with the decided fields, normalize and - validate through existing resolution/validation callbacks, and capture them - in the immutable backend index. Deep-copy optional nested values on lookup. -2. Implement the public convenience types and `BackendSource` translation. - Preserve existing convenience omission rules; do not add a parallel loader. -3. Test absent/null blocks, effective nested overlays, explicit endpoint fallback, - invalid final adapter/URL/default syntax, and owned convenience input values. - Show that an invalid lower contribution replaced by a valid final value is - not separately domain-validated. -4. Confirm a dangling default-profile reference is retained until selected and - does not invalidate ordinary engine construction. No provider contact. - -Validate: `go test ./internal/configuration ./internal/backend` and focused root -backend-source tests. Update backend-field GoDoc and `docs/formats.md` as these -configuration fields land; runtime smoke-test guidance waits for Stage 18. - -**Completed: 2026-10-13.** Validation passed: -`go test ./internal/configuration ./internal/backend`, `go test .`, and -`git diff --check`. - -## Stage 3: Resolve Diagnostic Targets Without Preparing Applications - -Scope: selection helpers in `internal/usecase`; no transport. - -1. Add the diagnostic selector using `resolvePromptInspection`, captured profile - selection, execution override merging, and captured backend lookup. -2. Implement the roadmap's prompt/profile/backend-default precedence exactly. - An explicit profile wins over a backend hint; selecting A's default may route - to B or to an endpoint-only profile without recursive default lookup. -3. Split model completeness from shared settings/base-endpoint validation so - HTTP probes can use profile metadata without a model. Backend-only selection - never loads a default inference profile. Resolve exact diagnostic destinations - and retain the base execution settings separately in the target report. -4. Validate kinds/retry overrides and selections without resolving application - artifacts, session templates, inputs, messages, or output schemas. - -Validate: focused `internal/usecase` tests for the selection table, explicit -selection failure, default-reference failure only on use, cross-backend/default -identity, endpoint-only profiles, and HTTP model incompleteness. Use real captured -configuration and failing external readers to prove no application preparation. - -**Completed: 2026-10-13.** Validation passed: `go test ./...`, `go vet ./...`, -and `git diff --check`. - -## Stage 4: Add OpenRouter Catalog Diagnostic Assets - -Scope: `../promptkit-backend-openrouter` only, plus this plan's completion record. - -1. Add the opt-in embedded root/constant and keyed backend metadata decided above. - Leave existing `Root` assets and model inventory unchanged. -2. Add a small asset-surface test for the new root and its shipped declaration. - Reuse existing YAML test helpers; do not add runtime adapters or PromptKit - imports to the catalog. -3. Document the opt-in root and its relation to existing `/v3` consumers in the - README. Clarify that selecting new metadata requires a compatible loader. -4. Run the catalog's local checks with `GOWORK=off`; review and commit. Create - an annotated, unused local candidate tag using the catalog version-selection - rule described under Stage 6. Record the full peeled commit and tag here. - Do not require remote synchronization, publication, or a public fetch. - -Validate: offline tests, race tests, vet, build, formatting, and local hygiene -from the catalog runbook. Its remote-publication checks belong to later release -preparation, not this local-candidate step. - -**Completed: 2026-10-13.** OpenRouter candidate `v3.20261013.0` points to -peeled commit `2a69672b1bb220f1a730153341470f5ac67e15f4`. Validation passed: -`GOWORK=off GOPROXY=off go test ./...`, `go test -race ./...`, `go vet ./...`, -`go build ./...`, formatting, `git diff --check`, and module identity via -`go list -m`. The annotated tag is local only; no publication or push was made. - -## Stage 5: Add RakestrawHome Catalog Diagnostic Assets - -Scope: `../promptkit-backend-rakestrawhome` only, plus this plan's completion record. - -1. Add the same opt-in root/constant with its existing Gemma profile as the - diagnostic default and authentication `kind: none`. -2. Leave existing base endpoint, credential environment name, capacity limits, - profile data, and ordinary execution credential policy unchanged. Declaring - authentication inapplicable does not alter generation's credential settings. -3. Add the focused asset test and README explanation as in Stage 4. Validate, - commit, and locally tag independently; record the tag and full commit here. - -Validate: the same local catalog checks, without provider access or publication. -Both catalog changes must be complete before PromptKit selects their new roots. - -**Completed: 2026-10-13.** RakestrawHome candidate `v3.20261013.0` points to -peeled commit `d40a8aad50111c15d279469170f7b5032ac22529`. Validation passed: -`GOWORK=off GOPROXY=off go test ./...`, `go test -race ./...`, `go vet ./...`, -`go build ./...`, formatting, `git diff --check`, and module identity via -`go list -m`. The annotated tag is local only; no publication or push was made. - -## Stage 6: Adopt Exact Catalog Candidates Through Local Module Resolution - -Scope: `internal/catalog`, module pins/checksums, attribution, integration tests; -temporary tooling stays outside all three repositories. - -1. Choose candidate versions independently as `v3..`: - use today's UTC date and the first unused local revision, monotonically above - the selected version. These are local candidate identities, not claims of - publication. Do not overwrite existing tags. If tagged contents need changes - later, commit them and choose a new candidate revision rather than reuse its - already-adopted identity. -2. A `mktemp -d` workspace may contain an uncommitted `go.work` selecting all - three checkouts for development. Set `GOWORK` explicitly when using it; never - commit workspace files or filesystem `replace` directives. -3. Build a temporary filesystem module proxy from the exact peeled catalog tag - commits. A small scratch Go helper can use the already-selected - `golang.org/x/mod/module` escaping helpers and - [`zip.CreateFromVCS`](https://pkg.go.dev/golang.org/x/mod/zip#CreateFromVCS) - to generate compliant archives. Do not add a production proxy tool or forge - module-cache entries. Supply each escaped module/version's `.info`, `.mod`, - `.zip`, and version list under `@v`, following the - [Go proxy protocol](https://go.dev/ref/mod#goproxy-protocol). - `.mod` comes from that commit; `.info` uses its version and commit UTC time. -4. Cache existing dependencies before switching resolution. For this workflow - only, use `GOWORK=off`, `GOPROXY=file://`, - `GONOPROXY=none`, and `GONOSUMDB` scoped to the two catalog module paths. - Existing dependencies can use the existing download cache as a second local - filesystem proxy. Do not change global Go environment configuration. -5. Update both ordinary `/v3` requirements to the exact candidates with the Go - tool; let it generate `go.sum`. Include both exported roots in the existing - strict catalog composition group, ahead of existing PromptKit-owned profiles - and caller overlays. Do not hard-code provider metadata in PromptKit. -6. Update selected module/version and commit-pinned notices in attribution after - checking each candidate's notices. Keep the existing licenses unchanged unless - the actual upstream material changed. Update stale selected-catalog references - in format/internal docs where needed. -7. Test shipped defaults through the final assembled configuration, including - `promptkit-openrouter-standard`, and test caller replacement/null behavior. - Do not separately parse or audit source contributions in PromptKit. - -Validate: `GOWORK=off go test ./internal/catalog ./internal/configuration` plus -focused assembled-construction tests under the temporary proxy environment. -Verify `go list -m -json` reports the exact versions and no replacement. Record -the tag-to-commit mapping here, not temporary paths. Later publication must use -the actual UTC publication date; if new version names are needed, retain the -validated contents and update PromptKit's pins/checksums before its release. -Publication and public module availability are not sprint completion gates. - -**Completed: 2026-10-13.** Adopted the local OpenRouter candidate -`v3.20261013.0` at `2a69672b1bb220f1a730153341470f5ac67e15f4` and RakestrawHome -candidate `v3.20261013.0` at `d40a8aad50111c15d279469170f7b5032ac22529`. Validation passed -through a temporary filesystem module proxy: focused catalog/configuration -tests, `go test ./...`, `go vet ./...`, `go mod verify`, exact module identity -and version checks with no replacements, and `git diff --check`. No workspace or -proxy artifacts were committed; the candidate tags remain local and unpublished. - -## Stage 7: Capture Destination-Specific HTTP Evidence - -Scope: shared transport helpers in `internal/llm`, independent of generation. - -1. Add an invocation-local evidence collector and client-copy execution helper. - Wrap the actual selected RoundTripper and preserve standard redirect policy. -2. Record each observed outgoing request's destination and credential presence, - retaining only the last hop; clear previous response/status facts when a new - request is observed. Record response availability/status before body decoding - or caller-context handling can discard it. -3. Keep dispatch invocation distinct from observed transport evidence. Handle - redirect-policy termination and response-plus-error according to what was - actually observed; do not infer a later dispatch from a Location header. -4. Exclude URL user information from exposed endpoints and keep credential/body - values out of collector records. Provide plain GET support reusing the built-in - configured client and target timeout without introducing public methods. - -Validate: focused adapter tests with `httptest` or controlled transports for a -response, no response, credential-stripping redirect, failed redirected hop, and -redirect-policy termination. Verify the supplied client is not mutated and -evidence is isolated across concurrent calls. Test facts, not wrapper choreography. - -**Completed: 2026-10-13.** Added invocation-local last-hop HTTP evidence and -plain GET support over a shallow copy of the configured client. Validation -passed: `go test -race ./internal/llm`, `go vet ./internal/llm`, -`go test ./...`, and `git diff --check`. - -## Stage 8: Retain Generation Evidence Before Result Discard - -Scope: `PreparedGeneration` execution in `internal/llm`. - -1. Add an evidence-enabled internal execution path sharing the existing frozen - payload, credential resolution, transport, size handling, envelope decoding, - usage decoding, and context error logic. Preserve ordinary `Execute` behavior. -2. Attach Stage 7 evidence to attempt outcomes. Retain decoded-response success - and usage before context checks overwrite an error/result. -3. Distinguish HTTP response acquisition from successful envelope decoding and - generated-content availability, including empty decoded content. Native-schema - request presence is known at dispatch; no provider-enforcement inference. - -Validate: focused `internal/llm` tests for valid/empty/malformed generation, -non-success status, and a decoded response followed by cancellation. Reuse -existing envelope/usage/size tests rather than reproduce their full matrices. - -**Completed: 2026-10-13.** Added an evidence-enabled prepared execution path -while keeping ordinary execution on its existing HTTP path. Validation passed: -`go test -race ./internal/llm`, `go vet ./internal/llm`, -`go test ./...`, and `git diff --check`. - -## Stage 9: Carry Evidence Through Built-In Retry Coordination - -Scope: `internal/generation` and shared observation usage accounting. - -1. Add `GenerateWithEvidence` using the same private built-in attempt/retry loop - as `Generate`. Collect attempts before ordinary result-discard checks. -2. Preserve status retry eligibility, frozen payload/credentials, active-permit - lifetime, jitter, and Retry-After handling. Add no network/validation retries. -3. Collect capacity waits and elapsed backoffs, including interrupted backoffs. - A canceled acquisition can produce an undispatched record; backoff alone does - not produce an attempt. Preserve last dispatched evidence independently. -4. Make the existing failure classifier internally reusable. Share existing - presence-aware usage aggregation with diagnostics, extracting a small - accumulator from `internal/observation` if needed; preserve its existing tests - and no-dispatch known/complete-zero semantics. - -Validate: coordinator tests using its controlled clock/wait seams for one -attempt, retry-success, exhausted retries, cancellation during backoff, and -canceled reacquisition. Check evidence retention and timing/accounting; existing -retry tests own unchanged retry policy. Run observation tests after extraction. - -**Completed: 2026-10-13.** Added built-in generation attempt evidence and shared -presence-aware usage accumulation. Validation passed: `go test -race -./internal/generation ./internal/observation`, `go vet ./...`, `go test ./...`, -and `git diff --check`. - -## Stage 10: Retain Injected-Client Evidence Without HTTP Claims - -Scope: the injected branch of `internal/generation`. - -1. Extend the shared evidence path to one injected dispatch using the same active - manager. Preserve the existing no-automatic-retry rule. -2. Capture returned response availability, successful generation/usage, and - native-schema request presence. Retain successful decoded content privately - if cancellation is observed immediately after the client returns. -3. Keep destinations, HTTP status/reachability, and upstream credential-supply - facts unknown. A response returned alongside an error establishes receipt, - not successful generation or content conformance; retain existing injected - usage policy rather than inventing billing completeness on errors. - -Validate: injected coordinator tests for success, nil response, opaque failure, -response-plus-error, and success followed by caller cancellation. Verify one -dispatch despite a positive retry allowance and ownership at the existing client -adapter boundary. Do not add methods to public `LLMClient`. - -**Completed: 2026-10-13.** Injected generation now records one-call response, -completion, usage, and native-schema-request evidence without HTTP claims, while -ordinary generation behavior remains unchanged. Validation passed: -`go test -race ./internal/generation .`, `go vet ./...`, `go test ./...`, and -`git diff --check`. - -## Stage 11: Implement The Reachability Probe - -Scope: internal HTTP probe collaborator and focused use-case support decisions. - -1. Resolve the chosen full diagnostic endpoint or effective base and perform - exactly one unauthenticated GET with the selected built-in HTTP client. -2. Report any observed HTTP response as reachable/received, independently of its - status. Report transport failure without guessing DNS/TLS subcategories. -3. Ignore inference retries for this operation after validating the option. - Never acquire a generation permit or require credentials/model completeness. -4. For injected-client engines, return the unsupported transport outcome without - falling back to another client. Preserve target selection errors as Go errors. - -Validate: internal probe tests for 2xx/401/404/405, transport failure, timeout, -and unsupported injected transport. Derive evidence from Stage 7 rather than -repeat redirect matrices here. Close response bodies; do not retain them. - -**Completed: 2026-10-13.** Added the unauthenticated, single-GET reachability -probe over the built-in evidence-aware HTTP client. It records any response as -reachable regardless of status, closes and discards bodies, and reports missing -HTTP support without fallback. Validation passed: `go test -race -./internal/usecase ./internal/llm`, `go vet ./...`, `go test ./...`, and -`git diff --check`. - -## Stage 12: Implement Authentication Applicability And OpenRouter Probe - -Scope: named HTTP authentication adapter; no inference orchestration. - -1. Evaluate captured metadata first: absent/null means unsupported/unknown - applicability; `none` means supported, inapplicable, completed, no dispatch. - Known inapplicability also works in injected-client engines. -2. For `openrouter_key`, use the selected full endpoint or base-relative `key` - path. Resolve direct/environment credentials consistently with generation, - permitting a missing key for this probe. Send at most one GET. -3. Implement the decided 200 recognition and 401 rejection. Preserve unknown - acceptance for other responses/transport failure, correct reason/failure - classification, and last-observed destination evidence. Discard account data. -4. Keep adapter choice fixed by metadata, not inferred from hostname, HTTP status, - or a models-list response. Reuse configured timeout and redirect behavior. - -Validate: focused adapter tests with synthetic current-key responses for accepted, -rejected, anonymous rejection, malformed/unrecognized 200, other status, and -transport failure. Add applicability/support tests without duplicating HTTP -client tests. Synthetic credentials must not appear in report-facing values. - -**Completed: 2026-10-13.** Added metadata-driven authentication applicability -and an OpenRouter key probe with optional direct/environment credentials. It -recognizes the documented minimal 200 response, records 401 rejection, leaves -other outcomes undetermined as specified, and distinguishes interrupted body -reads from malformed JSON. Validation passed: `go test -race -./internal/usecase ./internal/llm`, `go vet ./...`, `go test ./...`, and -`git diff --check`. - -## Stage 13: Build And Evaluate Private Inference Cases - -Scope: private fixtures and validation collaborators in `internal/usecase`. - -1. Add the fixed messages/schema described above, independent of application - prompt/profile listings and schema options. Create ordinary generation requests - from selected settings, using zero repairs and the diagnostic retry allowance. -2. Reuse prepared private schema validation for native schema request and local - conformance. Evaluate JSON syntax separately before evaluating the schema. -3. Populate text/JSON/schema facts only when evaluated; whitespace text returns - false, case changes do not match, invalid JSON leaves schema matching nil. - Keep malformed generation separate from content validation failure. - -Validate: focused case tests for match/mismatch/empty text, JSON parse failure, -schema failure, and success using real validators. Derive generated success -fixtures from the private case rather than spread private literals through tests. -No domain criteria, configurable prompts, public fixtures, or repair loop. - -**Completed: 2026-10-13.** Added private text and structured inference cases, -including an embedded schema prepared through `NewFSValidator`. Generation -requests retain the selected target and retry allowance; local evaluation keeps -JSON syntax and schema matching distinct. Validation passed: `go test -race -./internal/usecase ./internal/validate`, `go vet ./...`, `go test ./...`, and -`git diff --check`. - -## Stage 14: Orchestrate HTTP Diagnostic Reports - -Scope: `internal/usecase.SmokeTester` and its HTTP operations. - -1. Connect selection, support/applicability, and HTTP probes into a synchronous - operation. Start total timing before selection; HTTP probes bypass generation - capacity. Keep this internal while inference and engine wiring are completed. -2. Assemble HTTP attempts, measured phases, facts, reasons, and failure kinds. - Preserve nil unknown measurements and no-dispatch usage semantics. -3. Apply the decided Go-error/report boundary and mask inherited observation. -4. Distinguish outer cancellation from configured request timeouts; retain - previously established facts and finalize total timing on every report return. - -Validate: use-case tests for representative HTTP report-state rows, invalid -selection before dispatch, canceled-before-dispatch, timeout with live caller, -and available evidence after cancellation. Use real internal components with -controlled HTTP effects, not a new mock framework. - -**Completed: 2026-10-13.** Added the internal synchronous HTTP report -coordinator with captured selection, metadata applicability, timing, sanitized -report targets, per-attempt transport facts, and caller-cancellation handling. -HTTP probes bypass generation admission and inherited execution observation. -Validation passed: `go test -race ./internal/usecase ./internal/llm`, -`go vet ./...`, `go test ./...`, and `git diff --check`. - -## Stage 15: Integrate Inference Diagnostics And Engine Assembly - -Scope: inference orchestration in `internal/usecase` and `internal/engine` wiring. - -1. Connect private inference cases to the shared coordinator and existing - admission manager. Admit one logical diagnostic until it concludes; active - permits remain coordinator-owned and release during backoff/local evaluation. - Use the effective profile backend identity, including an empty identity. -2. Nil diagnostic retries means zero, independent of the engine default. Retain - all actual attempts, summed measured phases, aggregate usage, and last-dispatched - facts followed by generated-content evaluation. Keep interrupted waits from - replacing those facts. Do not run structural repair. -3. Turn local capacity exhaustion and missing required inference credentials into - concluded findings without dispatch. Apply the shared report/error and context - boundary, retaining decoded evidence without evaluating canceled content. -4. Assemble the engine's ordinary runner and smoke tester with the same snapshot, - coordinator, client, and capacity manager. Built-in engines supply the shared - HTTP collaborator; injected engines supply none. Do not change construction - options or public client methods. - -Validate: focused use-case/engine tests for text/schema results, retry-default -isolation, injected generation, required-credential/capacity findings, and evidence -after cancellation. Stage 17 owns broader facade-level capacity/observer regressions. - -**Completed: 2026-10-13.** Integrated private inference cases through the shared -generation coordinator, preserving attempts, usage, phase timings, last-dispatched -facts, and local validation findings. Required-credential and logical-capacity -findings conclude without dispatch. Built-in and injected engines share the -runner/coordinator while only built-in engines supply HTTP diagnostics. -Validation passed: `go test -race ./internal/usecase ./internal/generation -./internal/engine`, `go vet ./...`, `go test ./...`, and `git diff --check`. - -## Stage 16: Expose The Public SmokeTest Facade - -Scope: root declarations, GoDoc, conversions, and external-package API tests. - -1. Add the exact request/report method and public values from the feature roadmap - in a focused root file. Preserve the facade/internal ownership boundary and - existing public error translation. -2. Translate owned request values and reports, including a non-nil partial - report when a recognizable context error is returned. Add request formatting - redaction using established conventions; `APIKey` stays excluded from JSON. -3. Write complete GoDoc: nil Go error means concluded, not successful; tri-state - facts; selection precedence; HTTP transport support; retry/repair semantics; - configured timeout versus caller cancellation; timing and disclosure boundaries. -4. Cover nil engine, invalid kind, detached mutable values, concluded diagnostic - failure with nil Go error, and partial cancellation identity through the API. - -Validate: focused root `go test` cases plus internal engine tests. Do not copy all -internal selection/HTTP matrices into external-package tests or promise stable -JSON output for the new report types. - -**Completed: 2026-10-13.** Added the public `Engine.SmokeTest` facade, owned -request/report conversions, credential-safe request formatting, and GoDoc for -selection, tri-state facts, transport support, retries, timeouts, timing, and -disclosure boundaries. Validation passed: `go doc . Engine.SmokeTest`, -`go test -race . ./internal/engine`, `go vet ./...`, and `git diff --check`. - -## Stage 17: Verify Assembled Capacity, Cancellation, And Privacy Boundaries - -Scope: a small number of consequential integration regressions. - -1. Prove ordinary `Run` and inference `SmokeTest` on the same engine share a - test-controlled backend limit/admission bound. Verify permits release after - failure/cancellation and a later call proceeds. Avoid scheduler-order/fairness - guarantees and sleep-based synchronization. -2. Verify canceled retry backoff and later capacity wait preserve last-dispatched - facts/status/usage, report interruption separately, and do not add a synthetic - backoff attempt. Reuse lower-level tests for mechanical retry behavior. -3. Verify application prompt messages, inputs, session templates, artifacts, and - schema sources are unused, and private cases do not enter listings/inspection. -4. Verify reports/operational-error returns omit synthetic credential values, - generated text, provider messages, raw HTTP bodies, and private fixture content. - Verify diagnostic traffic does not enter an inherited execution observer. -5. Test a representative cross-backend default and endpoint override through the - facade with a controlled transport to prove selection/capacity/probe wiring. - -Validate: focused race-enabled tests for these assembled paths. Keep cases small -and each risk owned once; do not introduce a second end-to-end state-matrix suite. - -**Completed: 2026-10-13.** Added public-boundary regressions for shared Run and -SmokeTest admission, cancellation/failure permit recovery, retained HTTP and -decoded-usage evidence, application-resource and observer isolation, disclosure, -and cross-backend default routing with an endpoint override. Existing focused -generation/use-case tests continue to cover deterministic interrupted backoff -and undispatched reacquisition aggregation. Validation passed: -`go test -race . ./internal/usecase ./internal/generation ./internal/engine`, -`go vet ./...`, and `git diff --check`. - -## Stage 18: Complete Canonical Documentation - -Scope: GoDoc and existing consumer, format, integration, and internal owners. - -1. Add a consumer smoke-test section with minimal request/report handling, - explicit interpretation of nil error, optional facts, and a partial cancellation - example. Link to GoDoc for exact declarations rather than duplicate them. -2. Finish the backend-format reference for defaults, named adapters, explicit - endpoints, null/overlay behavior, and opt-in catalog assets. Link the selected - catalog versions rather than promise provider availability or free tests. -3. Update integration/internal documents for observed HTTP evidence, private - fixtures, shared coordinator/capacity, operator-only configuration inspection, - and injected-client limitations. Update the internal inventory only for - components actually introduced. Add a brief README navigation link if useful. -4. Describe diagnostics as explicit live consumer operations, separate from the - offline default suite and release checks. Do not add a live example/check to - existing release tooling or make an extra maintained executable necessary. -5. Record the later release-note need and unpublished catalog handoff here. - Do not rewrite historical release notes or publish a release in this sprint. - -Validate: local documentation paths/anchors, GoDoc against implemented behavior, -and any changed example snippets through focused offline tests. No online link -availability or human sign-off gate. - -**Completed: 2026-10-13.** Updated the consumer guide, backend format reference, -OpenAI-compatible integration contract, internal component inventory and -diagnostic mechanics, and README navigation. The later release note should -describe the explicit live `Engine.SmokeTest` API and its operational boundary; -the selected catalog candidates `v3.20261013.0` remain local and unpublished -(OpenRouter `2a69672b1bb220f1a730153341470f5ac67e15f4`, Rakestrawhome -`d40a8aad50111c15d279469170f7b5032ac22529`). Publication-date re-pinning may be -needed before a distributable PromptKit release. No release note was rewritten -and no catalog or PromptKit publication was attempted. Validation passed: -local Markdown paths/anchors, public GoDoc review, `go test . -run Smoke`, -`go test ./internal/usecase -run Smoke`, and `git diff --check`. - -## Stage 19: Validate The Integrated Candidate And Record Handoff - -Scope: final verification, completion records, and unintended-file cleanup. - -1. Rebuild the temporary proxy from the recorded exact tags if necessary. From - an isolated temporary module/cache, resolve both selected catalog versions - with `GOWORK=off` and that proxy, verify module identities/versions and no - replacements, and compare Go-generated sums with the adopted requirements. - Do not use local checkout substitution for this proof. Other dependencies can - resolve from the prepared existing local download-cache proxy. -2. Run the integrated PromptKit suite with `GOWORK=off` and local proxy settings: - `go test -race ./...`, `go vet ./...`, and - `python3 scripts/check-examples.py`. Check Go formatting, `git diff --check`, - local documentation links, and absence of committed workspace/replacement or - proxy/cache artifacts. These are sprint checks, not additions to release gates. -3. Reuse successful catalog checks for unchanged tagged candidates. Ensure all - three repositories' intended changes are committed; preserve and report any - unrelated work. Correct discovered defects with focused tests/commits and - rerun only checks invalidated by those changes. -4. Mark completed stages and record final catalog versions/full commits, - validation results, and the publication handoff below. Explain that catalog - tags/pins have been validated locally but not necessarily published, and that - publication-date re-pinning may be needed before a distributable release. -5. Report completion without waiting for public module fetches, provider access, - CI, human review, or separate loader/catalog releases. Publication of catalogs - and PromptKit follows their documented procedures under separate authority. - -**Completed: 2026-10-13.** Rebuilt the file proxy from the exact local -OpenRouter and Rakestrawhome candidate tags and resolved both versions from an -isolated module and build cache with `GOWORK=off`, no workspace, and no module -replacements. Go-generated module and `go.mod` checksums match the adopted -`go.sum`; `go mod verify` passed. The integrated checks passed with the local -proxy and `-mod=readonly`: `go test -race ./...`, `go vet ./...`, and -`python3 scripts/check-examples.py`. Tracked Go formatting, local Markdown -links/anchors, and `git diff --check` passed. No workspace, proxy, or cache -artifact is committed. The PromptKit and both catalog working trees are clean; -the catalog candidates remain local and unpublished. No provider requests, -public module fetches, CI checks, pushes, or releases were part of this -validation. - -## Completion And Publication Handoff - -All 19 work units are marked complete. The selected local catalog candidates -are OpenRouter `v3.20261013.0` at peeled commit -`2a69672b1bb220f1a730153341470f5ac67e15f4` and Rakestrawhome `v3.20261013.0` -at peeled commit `d40a8aad50111c15d279469170f7b5032ac22529`. Their module -identities, checksums, and integrated use were validated locally; the candidate -tags and PromptKit pins have not been published and may need publication-date -re-pinning before a distributable release. A future release note should -describe the explicit live smoke-diagnostic API and its operational boundary. -Catalog publication and PromptKit release preparation follow their separate -documented procedures. Temporary environment paths are not durable integration -metadata. +All prompt repository, compiled-template, and requirement-snapshot lookups use +ID alone. Remove ambiguity tracking, version selectors, version ordering, and +request assertions. Keep `PromptIdentity.ID`; change `PromptIdentity.Version` +to `*string`. Keep output field names `PromptVersion`, changing their types to +`*string` wherever they describe the selected label: prepared details, run +results, prompt/requirement inspection, execution events, and smoke-test targets. +The internal definition uses `Version *string` with equivalent semantics. +Each returned mutable pointer is owned by its result, including events and +prepared snapshots. JSON `omitempty` omits nil while preserving a declared +empty string. Preserve other existing serialization choices. + +The optional label remains part of captured definition metadata and its existing +definition-hash projection. Copy the pointer; do not dereference it as a cache +or selection key. No cross-release hash-stability promise is introduced. +Derive automatic structured-output schema names from the selected prompt ID +using the existing sanitization, not from a version-selection token. Keep explicit +schema selection and structural validation behavior unchanged. + +### Immutable Scope On The Existing Engine + +```go +type Namespaces struct { + Prompt string + Profile string + Backend string +} + +func (e *Engine) WithNamespaces(namespaces Namespaces) (*Engine, error) +``` + +Return another engine facade over the same assembled engine components with +immutable scope values. An internal engine view may be a shallow copy containing +the same runner, smoke tester, inspection, and inventory collaborators. It does +not invoke `NewEngine` or build another capacity manager. `WithNamespaces` +replaces all three scopes on the new view; empty fields clear those scopes. +The receiver is unchanged. Validate syntax, not namespace existence. Use the +existing invalid-configuration convention for an invalid engine or scope. + +At the internal engine entry boundary, use shared qualification helpers for +caller-supplied IDs. Validate supplied syntax; leave omitted optional IDs empty; +qualify slashless nonempty IDs for the applicable scope; pass qualified IDs +unchanged. The runner continues exact lookup. Do not requalify configured default +profiles, backend references, sibling inheritance, or diagnostic defaults. + +Apply the same policy to `Run`, `Prepare`, `PrepareExecution`, `ValidateRequest`, +`InspectPrompt`, `InspectProfile`, `InspectRequirements`, and all three selection +fields of `SmokeTest`. `ValidateRequest` already delegates to preparation; use +that route rather than adding another validator. `RunPrepared` consumes its +captured selection without qualification. Preserve its existing runner-ownership +check; scope does not introduce another handle owner. `InspectConfiguration` +continues to expose the complete retained configuration, not a filtered/re-keyed +view. Results and observer metadata carry full selected identities. + +### Listing Filters And Inventory + +Use one concrete optional filter argument for profile, prompt, and new backend +listings: + +```go +type NamespaceFilterMode uint8 + +const ( + NamespaceDefault NamespaceFilterMode = iota + NamespaceNamed + NamespaceUnqualified + NamespaceAll +) + +type NamespaceFilter struct { + Mode NamespaceFilterMode + Name string // Used only by NamespaceNamed. +} + +func (e *Engine) ListProfiles(ctx context.Context, filter ...NamespaceFilter) ([]string, error) +func (e *Engine) ListPrompts(ctx context.Context, filter ...NamespaceFilter) ([]PromptIdentity, error) +func (e *Engine) ListBackends(ctx context.Context, filter ...NamespaceFilter) ([]string, error) +``` + +Zero or one filter is accepted; multiple filters or an unknown mode return the +ordinary invalid-request error rather than guessing precedence. Omission and a +zero filter mean default: use that resource's scope, or all resources when it is +unset. Named requires a nonempty valid namespace. Unqualified selects IDs without +a slash; All includes every ID. A non-Named mode ignores `Name`. An explicit +filter replaces, not intersects, the view's default for that call. Keep IDs +full, sort lexically by full ID, and retain existing context, ownership, and +empty-list behavior. Copy optional labels on returned prompt entries. +Qualified results can be reused through any view. To select an unqualified ID +returned by an explicit All/Unqualified filter, use the original engine or a view +without that resource scope; a listing filter never changes execution scope. + +Add the following small discovery surfaces: + +```go +type ResourceKind string + +const ( + ResourcePrompt ResourceKind = "prompt" + ResourceProfile ResourceKind = "profile" + ResourceBackend ResourceKind = "backend" +) + +func (e *Engine) ListNamespaces(ctx context.Context, kinds ...ResourceKind) ([]string, error) + +type CollectionInfo struct { + Namespace string + ReleaseVersion *string +} + +func (e *Engine) ListCollections(ctx context.Context) ([]CollectionInfo, error) +``` + +No kinds means the union of all three resource types. Supplied kinds select their +union; repeats are harmless and unknown kinds are invalid requests. Namespace +enumeration describes resource membership across the captured engine, independent +of view scopes. Return distinct named namespaces sorted lexically; exclude the +unqualified group. Collection inventory likewise covers the entire captured +`collections` mapping, sorted by namespace, including metadata-only and +resource-only entries. It is not filtered by a view and does not include an +invented root collection. Both surfaces use the existing listing-style nil-engine +and context error conventions and return detached values. They do not inspect +historical sources, reopen files, or assert package authenticity. + +Capture sorted inventories once at construction. Namespace buckets or sorted +ranges may avoid repeated full scans for filtered listings. Prefer a single +resource traversal plus sorting and ordinary indexed lookups; no repeated +ConfigKit queries, definition deep copies for identity-only listings, global +caches, or performance/complexity promises in the public API are needed. + +### Collection Input Convenience + +```go +func CollectionInput(namespace string, source configkit.Source) (configkit.Input, error) +``` + +Validate the required namespace syntax and return an input with that source, +`Destination: configkit.Keys("collections", namespace)`, and `Imports: true`. +Invalid namespace syntax returns an error matching `ErrInvalidConfig`. +Do not open/read the source or infer a namespace/filename. ConfigKit still owns +source validity and loading errors. The caller may change the returned input's +imports, filesystem context, or destination, or construct an input directly. +This supports host, embedded, and mapping sources with one helper, without +introducing another loader or options framework. Directory/Filesystem helpers +retain their existing explicit discovery and imports-disabled semantics. +`ProfileSource` and `BackendSource` retain their root-document shapes and can be +mounted with this helper. Direct local-key fragments use explicit ConfigKit +destinations that include the resource category. + +### Migration Choices + +Do not mass-copy the provider inventories into PromptKit or create a mandatory +replacement bundle. Provide synthetic, complete collection examples and guidance +for adapting selected existing catalog configuration. Adjacent repositories and +their publication are outside this sprint. The reviewed pinned catalog assets +have slash-free profile keys, so these explicit mappings are collision-free +within those assets: + +| Previous identity | Documented migration identity | +| --- | --- | +| Backend `openrouter` | `openrouter/default` | +| Backend `rakestrawhome` | `rakestrawhome/default` | +| Each OpenRouter catalog profile `p` | `openrouter/p`, retaining the exact local key `p` | +| Profile `rakestrawhome-gemma-4-31b` | `rakestrawhome/rakestrawhome-gemma-4-31b` | +| Built-in `promptkit-openrouter-standard` | No automatic replacement; optional caller profile `openrouter/standard` | +| Built-in `promptkit-openrouter-auto` | No automatic replacement; optional caller profile `openrouter/auto` | + +These are documented conversions, not installed aliases. Simply mounting old +`/v3` assets does not update their stored backend/profile references; those +references and diagnostic defaults need the explicit edits shown here. + +For an optional caller standard profile, `extends: gemini-flash-latest` is valid +only within the same `openrouter` profiles mapping containing that base. The +caller auto profile may explicitly set backend `openrouter/default` and model +`openrouter/auto`. Neither name becomes a PromptKit promise. Move backend +diagnostic defaults to exact new profile IDs. Preserve endpoint/settings and +provider model strings, including the pinned Gemini model's leading `~`. + +Application-specific IDs require a deliberate collision review, not automatic +slash-to-dot replacement. For a formerly multi-version prompt, its maintainer +chooses the installed definition; examples use the single definition already +present. Put its old version string into optional metadata where useful. Do not +select a winner from a consumer's multi-version history by guessed ordering. +Document exact references, paths, backend capacity identity changes, source-root +header reservations, label null/empty semantics, and the loss of cross-mapping +inheritance. Migration documentation is not a runtime migration tool. + +## Stage 1: Adopt The Released ConfigKit Prerequisite + +Scope: dependency selection and existing integration compatibility only. + +1. Select ConfigKit `v0.8.0` with normal Go module tooling; update `go.mod` and + `go.sum` without filesystem replacements. Verify the selected release commit + and notices; update its attribution entry with the full commit above. +2. Check affected keyed literals and source-inspection handling for upstream + additions. `SourceInfo` is no longer comparable; compare relevant fields if + PromptKit currently relies on comparability. Do not enable new schema behavior. +3. Leave Go's consumer minimum at `1.26.0` unless the selected dependency actually + requires a higher minimum. Leave unrelated dependencies/tooling unchanged. + +Validation: `GOWORK=off go test ./internal/configuration .` and the three offline +examples, including configuration inspection/diff coverage. This stage establishes +the unchanged PromptKit baseline on the new dependency. + +## Stage 2: Add Shared Resource Naming Primitives + +Scope: small private domain helpers and focused behavior tests. + +1. Implement exact ID parsing/validation, namespace syntax validation, local-key + validation, qualification, and namespace extraction as needed by later stages. + Keep omission policy in operation callers, not a universal required-ID rule. +2. Cover unqualified/dotted names, qualified bypass, missing/empty scope, + malformed slash forms, and preserved spelling. Check that namespace matching + is exact rather than a prefix match. +3. Do not wire names into all public operations yet or export a splitting API. + +Validation: `GOWORK=off go test ./internal/domain`. Test selected naming behavior, +not a helper call sequence or invented character restrictions. + +## Stage 3: Make Configuration Processing Path-Aware + +Scope: preparation refactor inside `internal/configuration`; current format stays. + +1. Refactor `captureFields`, `resolveBackends`, `resolveProfiles`, + `validateEffective`, prompt metadata capture, and prompt materialization to + accept/use explicit effective base paths. Preserve current values and errors. +2. Carry a resource's public ID separately from its ConfigKit path. Stop deriving + an effective path by splitting a runtime ID. Use ConfigKit path segments for + literal keys and preserve inherited `content_file` origins. +3. Factor resource-map traversal only as needed to reuse the same processing + for root and collection mappings later. Do not add a generic visitor framework. +4. Prepare the existing provider-secret predicate to recognize actual resource + paths without mistaking arbitrary nested `extra_params` data for resources. + Keep its existing protected-key policy. + +Validation: configuration load, target, prompt-origin, inheritance, and inspection +tests; `GOWORK=off go test ./internal/configuration .`. A behavior-preserving +refactor should not rewrite unrelated expectations. + +## Stage 4: Install One Prompt Definition Per ID + +Scope: prompt storage format, materialization, and fixture-format migration. + +1. Change root `prompts` to `map[string]promptConfig`; add nullable + `Version *string` to the raw prompt definition. Materialize one entry per ID, + preserving the label text without normalization or a generated label. +2. Remove nested version indexes, ambiguity tracking, and selection-by-version + from the configuration adapter. Use the actual prompt path without the old + version segment for metadata and message resources. +3. To keep this stage bounded, existing repository method parameters and public + selector fields may remain only until Stage 5. At this adapter boundary their + temporary implementation delegates to ID-only lookup; do not compare them + with labels or create an assertion mode. Existing string-valued output labels + are converted to presence-aware values in Stage 6. These are migration seams, + not new compatibility behavior to retain or publish. +4. Mechanically migrate YAML fixtures, mapping builders, and example configuration + files to the direct definition shape. Move retained version keys to quoted + metadata. Replace tests of parallel versions/ambiguity with one-entry lookup + and ordinary mapping-overlay cases. Keep unrelated validation coverage. + +Validation: `GOWORK=off go test ./...`, including consumers of migrated fixtures. +Test ID-only selection, source-relative content, and inherited/overlaid prompt +settings. Do not add tests preserving temporary obsolete selector parameters. + +## Stage 5: Remove Request-Side Version Selection + +Scope: compile-directed removal of obsolete selector plumbing; no new lookup rules. + +1. Remove request `PromptVersion` fields and the version parameter from public + `InspectPrompt` and internal prompt repository/snapshot/template interfaces. + Update runner preparation, inspection, requirements, and smoke selection. +2. Update public-to-internal conversion, redacted formatting, fakes, tests, + examples, and call sites. Remove version-without-prompt checks and the + transitional signatures from Stage 4. Preserve ordinary not-found identities. +3. Use the selected prompt ID for generated structured-schema names; retain the + existing sanitization and explicit schema behavior. Do not remove output + metadata fields merely because selectors are gone. +4. Update affected GoDoc now so obsolete selectors are no longer advertised. + +Validation: `GOWORK=off go test ./...` and focused vet of modified packages. +Search declarations/call sites for remaining selection/ambiguity logic; descriptive +label references are valid and should not be blanket-deleted. + +## Stage 6: Carry Optional Prompt Labels Through Results + +Scope: presence-aware metadata across internal values and the facade. + +1. Change internal definition `Version` and all selected-label output fields + identified above to `*string`. Read the raw optional field captured by Stage 4. + Update conversion and ownership copies, hashing projection, requirement + snapshots, observation selection/events, prepared details/results, and smoke + target projection. Optional labels never become lookup keys. +2. Distinguish nil from a declared empty string in inspection/listings and JSON. + Both omitted and null mean no label; a higher-layer or inherited null clears + the label through ordinary ConfigKit composition. +3. Update the example summary types and test expectations. Add focused boundary + coverage for absence, null clearing, empty/exact text, and pointer ownership; + reuse existing report/prepared/event detachment tests where practical. + +Validation: domain, promptdef, configuration, observation, usecase, and root tests; +`GOWORK=off go test ./...` and the offline examples. Verify the existing selected +definition hash still agrees between inspection and preparation. + +## Stage 7: Enable Shared Specification Checking + +Scope: root declaration policy through ConfigKit's released version API. + +1. Add optional root `version` to the typed document. Configure the version rule + and `SourceVersionModeIfPresent` with the exact checker specified above. + Keep no-main and headerless sources valid. +2. Use ConfigKit's header consumption and source evidence without a source + pre-parser, validation loop, or PromptKit mode option. Nested prompt labels + remain ordinary metadata. +3. Cover accepted string/integer `1`, omitted main/header, rejected null or + unsupported declarations, consumed non-main headers, and an explicit main + declaration retained in inspection. A headerless imported prompt fragment + still undergoes ordinary final-value validation. + +Validation: focused real-ConfigKit tests in `internal/configuration` and public +construction/inspection tests. Do not replicate upstream's full version-type or +import matrix. Run `GOWORK=off go test ./internal/configuration .`. + +## Stage 8: Assemble And Index Final Collection Resources + +Scope: namespaced schema, final resource interpretation, and runtime indexes. + +1. Add `collections` and collection `release_version`/resource mappings to the + typed document. Visit root and collection maps using Stage 3's effective + paths. Validate namespaces/local keys; build full IDs only in runtime indexes. +2. Include backend/profile snapshots and prompt metadata/templates in that + traversal. Keep the retained ConfigKit result structurally unchanged. + Preserve the distinction between root unqualified and collection-local keys. + Migrate maintained qualified-key fixtures into collection/local-key mappings, + updating exact references and inspection paths together. Use ordinary explicit + destinations until the convenience helper lands; do not keep a second root + spelling for qualified identities. +3. Validate effective references with the naming helper and existing existence + policy. Local `extends` stays with ConfigKit. Do not reject repeated namespace + contributions, require collection releases, or qualify stored references. +4. Extend secret-path matching to backend/profile extras beneath collections, + preserving the existing protected-key list. Use exact effective paths for + field presence, normalization, `content_file`, explanations, and diagnostics. +5. Preserve backend-ID capacity policy wiring. The same final backend is one + capacity identity regardless of the sources that contributed its settings. + +Validation: focused real-ConfigKit tests for two collections with duplicate local +names, root resources, partial overrides, inherited relative content, explicit +zero/null settings, and redacted namespaced provider data. Include retained +release metadata, sibling inheritance, headerless collection fragments, resources +named `version` in nested mappings, and header/declaration distinctions. +Run `GOWORK=off go test ./internal/configuration .`. + +## Stage 9: Make Application Tests Independent Of Bundled Catalogs + +Scope: owned fixtures and examples that currently assume automatic provider data. + +1. Locate tests/examples using bundled backend/profile IDs, inherited catalog + settings, default smoke profiles, or baseline listing counts. Supply the + explicit synthetic definitions each behavior needs through existing sources. +2. Keep generic test helpers small and local; no full catalog snapshot or shared + test fixture framework. HTTP adapter tests may retain provider adapter names + but use controlled transports and synthetic configuration. +3. Keep catalog-specific assembly tests until Stage 10 removes the integration. + Do not preserve provider inventory assertions as application contracts. + +Validation: the affected root, engine, and usecase tests plus examples. Ordinary +coverage should now express its own backend, profile, and prompt requirements. + +## Stage 10: Remove Automatic Catalogs And Built-In Profiles + +Scope: engine composition, dependency/notices cleanup, and the retired promise. + +1. Remove `catalog.Underlays()` from `internal/engine.New`; load only caller + underlays and optional main. Preserve their order and strict-group semantics. + Empty configuration constructs an engine with empty resource inventories. +2. Delete `internal/catalog`, its owned profiles, and integration-specific tests + after checking references. Do not delete generic file-discovery helpers. +3. Remove both catalog module requirements and unused checksums through module + tooling. Do not update/publish those repositories or copy their inventories + into PromptKit as a replacement. +4. Update attribution for actual retained material; remove catalog dependency + entries when nothing incorporated remains. Keep a notice if other copied + material still requires it. Do not strip a shared license text still in use. +5. Retire the release policy's catalog-update exception and literal built-in-name + promise. Apply ordinary compatibility rules to PromptKit format/API changes; + independently selected configuration is no longer a bundled release inventory. + Update architecture/internal inventory and current format documentation for + the removed component. Preserve historical release notes. + +Validation: `GOWORK=off go test ./...`; verify empty inventories, explicit former +backend names still work when configured, and inference smoke tests retain their +selection/capability behavior with caller-supplied metadata. Review `go.mod`, +`go.sum`, imports, and notices for residual automatic catalog coupling. + +## Stage 11: Add The Explicit Collection Input Helper + +Scope: the single public convenience function and its GoDoc. + +1. Implement `CollectionInput` exactly as specified above, reusing namespace + validation and existing facade error conventions. It creates an input, not + an engine and not a configuration pre-parser. +2. Keep raw ConfigKit inputs and existing directory/filesystem/programmatic + helpers usable. Do not reinterpret their IDs or introduce root discovery. +3. Add one native-file and one embedded/mapping assembled case with entry + imports and a later deliberate override. Verify resource contexts survive. + +Validation: source-helper contract tests and focused configuration/root tests. +Verify helper construction itself performs no source read using an existing +controlled source seam where needed, rather than adding a production interface. + +## Stage 12: Add Immutable Scopes To Ordinary Execution + +Scope: public `Namespaces`/`WithNamespaces` and shared engine-boundary routing. + +1. Add the public facade and internal immutable view. Replace all scopes on each + new view without mutating its receiver. Reuse assembled collaborators. +2. Route caller prompt/profile selections in `Run`, `Prepare`, and + `PrepareExecution` through shared qualification. `ValidateRequest` follows + its current preparation route. Stored defaults and omitted IDs stay untouched. +3. Preserve resolved full IDs through prepared details, results, events, errors, + and selected backend identity. Leave `RunPrepared` captured and single-claim; + do not add a scope mismatch check or rebuild shared state. +4. Add public behavior tests for two independent prompt/profile scopes, + qualified bypass, no fallback, absent well-formed namespaces, and invalid + scope syntax. Assert the receiver retains its original behavior. + +Validation: root/prepared/usecase tests and focused race-enabled scope tests. +Use injected generation or a controlled HTTP boundary; never a live endpoint. + +## Stage 13: Apply Scopes To Inspection And Diagnostics + +Scope: complete the existing operation inventory without a second resolver. + +1. Route `InspectPrompt`, `InspectProfile`, and `InspectRequirements` through the + same helpers; resolve each request's explicitly supplied prompt/profile fields + independently. Keep configured references exact. +2. Route `SmokeTest`'s supplied PromptID, ProfileID, and BackendID by their own + scopes before ordinary diagnostic selection. Keep its precedence, optional + omissions, backend defaults, factual reports, and errors unchanged. +3. Keep `InspectConfiguration`/Diff global with effective ConfigKit paths. + Do not qualify schema paths, provider models, input identifiers, or overrides. +4. Review all public resource-selection entry points for omissions. Validate + malformed supplied reference syntax through the existing invalid-argument + boundary; retain ordinary not-found behavior for well-formed missing IDs. + +Validation: representative public inspection/requirements/validation/smoke cases +prove shared behavior and full identities. Reuse naming-helper tests instead of +duplicating the full syntax matrix in every API test. Run relevant root/engine +tests and focused race checks. + +## Stage 14: Add Backend Listing And Namespace Filters + +Scope: the existing identity-inventory path, not the execution runner. + +1. Add the filter declarations and optional arguments to profile/prompt listing; + add backend identity listing through configuration, internal engine, and facade. + Existing no-filter engine calls still enumerate everything. +2. Resolve default/explicit filters once per listing using the relevant view + scope. Validate named filters and modes; filter exact namespace membership. + Use captured sorted inventories, optionally indexed by namespace. +3. Return full IDs and detached optional prompt labels, with existing cancellation + and empty-result behavior. Do not materialize definitions for identity listing. + +Validation: extend listing tests with scoped defaults, explicit named/All/ +Unqualified overrides, no-scope defaults, absent namespaces, same-prefix namespace +names, full-ID round trips (and unqualified selection through the original +engine), invalid filters, ownership, and canceled contexts. Use a compact matrix +across resource types, not three copies of all tests. Run configuration/root tests. + +## Stage 15: Expose Namespace And Effective Collection Inventories + +Scope: the two discovery APIs and construction-time inventory capture. + +1. Capture namespace sets by resource kind from final indexed IDs; implement + `ListNamespaces` with the chosen union, kind validation, and global semantics. +2. Capture `CollectionInfo` values from final `collections` declarations. Preserve + absent/null versus empty/exact release labels, including metadata-only and + resource-only collections. Copy label pointers on output. +3. Delegate through the internal engine's narrow inventory boundary and root + facade. Do not derive collection releases from source header evidence or + confuse resource namespace membership with collection declarations. + +Validation: one representative inventory fixture covers cross-kind membership, +deduplication/sorting, unqualified exclusion, metadata-only collections, +scope-independent enumeration, effective overrides, cancellation, and ownership. +Run configuration/root tests; no file access or generation should be needed. + +## Stage 16: Maintain Complete Consumer And Migration Examples + +Scope: runnable/synthetic examples and precise migration guidance. + +1. Keep the existing prepare/run/observe examples valid with ID-only selection + and optional labels. Extend the preparation example, or its existing input + assets, to demonstrate two collections, explicit input selection, a scoped + view, filtering, and operator inventory without a provider call. Keep the + run/observe examples focused on their distinct existing workflows. +2. Add small complete collection entry/fragments under `examples/`, with optional + headers/releases, source-relative message content, exact stored references, + sibling inheritance, and an intentional later partial override. Use synthetic + endpoints/models rather than another maintained provider catalog. +3. Add `docs/consumers/configuration-migration.md` explaining the breaking format + and signatures, the explicit mapping table above, optional caller standard/auto + choices, and deployment selection responsibility. Do not promise arbitrary + consumer migrations are automatic or validate upstream provider availability. +4. Update semantic example checks only for the changed example outputs. If + script logic changes, run its focused checks; do not rewrite release tooling. + +Validation: `GOWORK=off python3 scripts/check-examples.py`. Assemble the maintained +collection example through real ConfigKit and PromptKit. Keep copied material's +actual attribution obligations aligned if any is introduced. + +## Stage 17: Finalize Canonical Contracts And Migration Documentation + +Scope: documentation consistency after the APIs and examples exist. + +1. Update GoDoc for all changed/new public declarations, errors, optional labels, + ownership, scopes, and listing behavior. Do not leave obsolete selectors or + an implication that a descriptive label controls execution. +2. Update `docs/formats.md` for the final schema, specification header policy, + source-root reservations, one installed prompt, exact references, local + inheritance, and explicit provider configuration. Keep current contracts here, + not in the migration guide or roadmap. +3. Update `docs/consumers/pkg-promptkit.md`, README quickstart/navigation, + `docs/internal/sources.md`, internal inventory, and affected runner/rendering/ + observation documents. Explain unchanged resource contexts and operator-only + provenance use. Remove live claims about automatically bundled inventories. +4. Review architecture, release policy/procedure, development reading guidance, + and attribution for obsolete catalog assumptions. Revise only affected local + statements; do not rewrite upstream policy language unnecessarily or weaken + ordinary compatibility promises. Do not revise historical release notes or + immutable ADR decisions. + +Validation: review changed Markdown links and example references, check GoDoc +against declarations, and run `git diff --check`. Release notes and version/tag +selection belong to the later requested release preparation, not this stage. + +## Stage 18: Verify Cross-Boundary Behavior And Close The Sprint + +Scope: focused integration gaps and final regression validation, not new features. + +1. Trace the feature roadmap's acceptance criteria to focused existing/new tests. + Add only missing assembled-boundary coverage. One synthetic fixture can prove + independent collection names, scoped execution/inspection, full-ID filtering, + exact defaults, optional labels, and inventory without duplicating every + assertion at each internal layer. +2. Use a controlled concurrent model boundary to verify ordinary and differently + scoped calls share the same configured backend's capacity. Reuse existing + admission/cancellation tests for queue mechanics. Verify prepared selections + remain captured when another view is used; no namespace is mutable global state. +3. Confirm final-value-only validation, source-local headers versus ordinary + metadata, retained inherited/overlaid content origins, and redaction under + namespaced paths. Final inspection still describes ConfigKit's original + effective shape rather than a rewritten runtime index. +4. Remove all temporary selector signatures/adapters from the migration stages. + Review source/tests/docs for old version-key maps, version selection/assertions, + automatic catalog contributions, mandatory built-in names, and local module + replacements. Historical notes and optional metadata references may remain. +5. Run the final offline checks once for the resulting content: + + ```sh + GOWORK=off go test -race ./... + GOWORK=off go vet ./... + GOWORK=off python3 scripts/check-examples.py + git diff --check + ``` + + Format changed Go files and validate affected Markdown links. Review the full + diff/status for unintended files and private data; commit the completed unit. + Mark this plan and the feature roadmap complete, leaving retirement to normal + release preparation. Do not publish, wait for CI, probe providers, or introduce + a catalog-release dependency to finish implementation. + +## Open Questions + +None required to begin implementation. The feature roadmap's policy decisions +are settled; the delivery decisions above specify the public shapes and migration +path. A newly discovered upstream incompatibility or genuine change of scope +should be reported with a recommendation and viable alternative rather than +silently changing the accepted configuration boundary or adding restrictions.