# ConfigKit Adoption Status: agreed feature roadmap. ConfigKit v0.5.0 supplies the required upstream capabilities. The [implementation plan](implementation.md) owns execution steps. The [configuration-boundary ADR](../adr/0001-configuration-boundary.md) records the handoff decision. This document owns the intended end state, not implementation authorization. ## Purpose Use ConfigKit to standardize PromptKit's configuration semantics and simplify its loading machinery, replacing custom logic wherever ConfigKit is the appropriate owner. Preserve substantive consumer capabilities, not historical file syntax, loading order, or Go signatures. Pre-1.0 breaking changes are acceptable and must have migration guidance. **This is an intentional breaking change. We are intentionally replacing PromptKit's configuration handling code in favor of adopting ConfigKit's simpler, standardized API. Our goal is to arrive at a new version of PromptKit that is leaner, simpler, and uses a ConfigKit-standard configuration syntax. We MUST NOT give any weight to preserving arbitrary implementation details from PromptKit's current codebase--those should be discarded in favor of the simplest viable implementation that supports PromptKit's substantive LLM-focused consumer capabilities.** Applications using both libraries should share configuration interpretation, layering, inheritance, presence, and inspection semantics. PromptKit should concentrate on LLM-specific validation, resource interpretation, and execution. The [adoption assessment](configkit-assessment.md) records the supporting analysis; this roadmap owns the agreed feature end state. Where the earlier assessment differs, this roadmap and the maintainer's direction above take precedence. Do not preserve source-option wrappers, repository interfaces, incidental error ordering, or old field shapes solely because they exist today. Reuse existing code only when it remains the simplest appropriate owner of a substantive capability. Migration documentation replaces compatibility machinery, not vice versa. ## Baseline And Dependency The current PromptKit runtime baseline is v0.11.2. Its [source implementation](../internal/sources.md), [format contract](../formats.md), and [consumer guide](../consumers/pkg-promptkit.md) describe existing behavior, not the target described here. The reviewed ConfigKit release is v0.5.0 at `dc09959cca4e105f49ec316c6d4ba585bd2340bd`. It provides native `fs.FS` sources, `LoadLayered`, source-backed underlays, labeled programmatic mappings, passive resource contexts, and built-in sibling inheritance. Its released configuration contract and GoDoc own exact upstream semantics. No further upstream feature is currently a demonstrated prerequisite. Review any newer version before selection. Adopt a released Go module, not a local `replace` or workspace requirement. Update attribution and transitive license notices under the OSS policy. This feature does not change either project's license or require a Go minimum increase relative to the reviewed versions. ## Substantive Capabilities To Preserve - Named/versioned prompts, declared-input inspection, templates, inline and referenced message content, variables, input helpers, roles, and cache control. - Maintained catalogs, application defaults, operator configuration, programmatic profiles, aliases/inheritance, built-in/custom/local backends, and endpoint-only profiles. - Preparation without generation, ordinary execution, and frozen single-claim prepared execution; independent prompt and profile inspection. - Runtime execution-setting, reasoning, session, credential, and output-contract overrides; appended already-rendered messages. - Inline/file input artifacts and injected artifact, model, and HTTP collaborators. - Backend capacity management, cancellation, transient retries, structural output validation, provider-native structured output, bounded repair, and observations. - Results, effective identities/settings, usage, hashes, and meaningful errors. Retain optional environment credentials and direct request credentials. ConfigKit secret resolution must not introduce a new requirement that an upstream API key exist. Domain validation must not probe provider/model availability. ## Target Configuration Model ### One Shared Loading Lifecycle Construction supplies selected configuration inputs to ConfigKit, which composes, overlays, expands inheritance, and decodes them. PromptKit interprets and validates the final effective configuration at the ConfigKit handoff and produces execution-ready definitions. ConfigKit's effective-value resolution and validation hooks may implement that handoff. Publish no partially initialized engine on failure. ConfigKit owns generic parsing, combination, presence, origins, and inheritance. PromptKit owns input selection/discovery, definition indexing, LLM-specific rules, and translation of final values into runtime settings. Input adapters select or encode contributions; they do not inspect or validate raw source contents. Effective presence/null information and resource context supplied by ConfigKit support interpretation at handoff. Historical inspection remains an explicitly invoked operator capability, separate from domain enforcement. Runtime clients and callbacks remain normal Go dependencies, not YAML types. Use `backends.`, `profiles.`, and `prompts..` keyed mappings assembled before typed decoding rather than independently decoding definitions and combining them afterward. Keys own identity; do not duplicate `id`/`version` fields. These paths describe mapping levels, not dot-splitting of literal IDs or version keys. Multiple files can contribute to a collection; a monolithic file is not required. When a prompt ID has multiple versions, selection without a version remains ambiguous. This shape fits sibling inheritance without extra identity reconciliation. Supply explicit source groups through a small construction surface compatible with ConfigKit's `Input`/underlay concepts. Offer convenient file/directory/embedded entry points where useful, not a parallel set of historical loading semantics. Accept ConfigKit's labeled mapping sources for programmatic configuration. Add only small typed conveniences justified by the minimal local-backend and application-profile workflows. Helpers encode explicit presence and feed the same loading lifecycle; they neither merge configurations nor infer omission from zeros. Backend helpers also produce inputs to this lifecycle. Backend definitions, including catalog connection and capacity settings, cross the same ConfigKit handoff as prompts and profiles. The immutable runtime registry is built from effective backend values. HTTP/model clients and other runtime collaborators remain outside typed configuration. Keep the public package a deliberate facade and implementation private. Do not expose internal engine/domain types or introduce a parallel generic loader merely to preserve old source options. ConfigKit's supported public types may be used where intentional integration is simpler than maintaining equivalent wrappers. ### Sources, Tiers, And Presence Support ordinary files/directories, embedded or caller-supplied `fs.FS`, and programmatic definitions. Explicitly selected directories may be discovered by PromptKit; ConfigKit handles their configuration contributions. Do not infer priority from traversal order. Retain the useful priority categories, lowest to highest: external catalogs, PromptKit-owned profiles, application fallback, operator configuration, and programmatic configuration. Express intentional priority as ordered tiers. Within each tier, independent contributions compose strictly; overlapping non-mapping values conflict, even when equal. Disjoint fields under the same identity can combine. Across tiers, mappings recursively overlay. These rules also govern backend configuration; consumers can add backend IDs or overlay existing definitions through their selected tiers. Registry construction validates the resulting values, not the identity of their contributors. Use ConfigKit's source roles honestly: underlay groups are ordered defaults, main input overlays underlays, and optional named overlay/CLI facilities retain their upstream meaning. Underlay-only loading is supported; do not manufacture a main document or disguise programmatic values as CLI flags. Exposing every ConfigKit convenience through PromptKit is not a requirement. Adopt the shared value rules: omission retains lower input; explicit zero, false, empty string, sequence, and null replace; mappings combine recursively; empty mappings do not clear lower children. Null remains explicit and subject to the final schema. Provider-parameter maps obey these rules too. No hidden whole-profile replacement, arbitrary merge callback, or new reset/delete operator belongs here. Preserve presence into execution-ready settings so an explicit zero does not disappear during backend/default resolution or outbound request construction. Use ConfigKit metadata at construction, not as a per-run lookup mechanism. ### Sibling Inheritance Use ConfigKit's reserved `extends` rather than PromptKit's `base_profile` and custom resolver. A string identifies an immediate sibling mapping; null cancels the relationship without deleting the child's own settings. Layering completes before inheritance. Only effective relationships resolve, but all of them do, including entries never selected for execution. Children recursively overlay resolved parents. Inherited values count as explicit input. Origins and resource context remain attached to their declaring source. Nested relationships follow ConfigKit's destination-local rules; defaults and application-derived values do not trigger another inheritance pass. The keyword is reserved throughout configuration, including dynamic provider maps; it is not opt-in. Keep runtime request provider-parameter maps ordinary JSON-compatible data outside configuration parsing. Consumers needing a literal provider field named `extends` supply it at that runtime boundary. Do not rename the outbound key or introduce a second opaque configuration format to escape it. Document and test this distinction, including any affected maintained payloads. ### Validation And Errors ConfigKit owns acquisition, syntax, composition, inheritance, and typed-decoding failures. PromptKit preserves those errors and validates final effective domain values. An unused invalid effective definition fails construction; a lower-layer value legitimately replaced by ConfigKit is not a separate validation target. This boundary applies equally to application and maintained catalog configuration. PromptKit does not perform catalog preflight, raw-source or intermediate-state validation, or history-based enforcement, including equivalent test-only checks. Catalog maintainers own publishing checks in their respective repositories. Domain validators remain shared with runtime request validation where appropriate. Allow schema-valid partial profiles without an `abstract` flag. Validate supplied domain values at loading; final runnable-target requirements are checked after profile selection and runtime overrides at execution preparation. Do not require credentials, artifacts, or provider connectivity during construction. Preserve absence versus explicit null in resolved settings. Null on an optional provider setting deliberately suppresses it; it must not restore the same setting from backend defaults. A null provider map suppresses the configured lower map, while null entries inside a provider map remain literal JSON null values. This supports reusable bases and deliberate removal of stale settings without changing ConfigKit's merge rules. Framework-required settings such as timeouts have explicit field-specific null semantics rather than blanket nil defaulting. Preserve ConfigKit public loading errors through wrapping for `errors.As`, with a PromptKit configuration category. Use source-aware domain/resource failures where ConfigKit is not the owner. Do not mirror its diagnostic framework or promise aggregation beyond what the underlying operation provides. Runtime operational errors remain distinct from generated-content validation failures. Prompt versions are domain identifiers, not ConfigKit `VersionRule` declarations. Do not introduce an application schema-version policy merely to adopt ConfigKit. ## Snapshot, Resource, And Execution Boundaries The engine captures effective definitions and referenced message text during construction. Validate static template syntax then; render with request data later. Resolve content references from the effective field's contributing source context, not the last layer's directory. Ambiguous/contextless resource references need an explicit source context or an actionable error, not an invented directory. ConfigKit returns passive resource contexts, not snapshots of referenced text. PromptKit explicitly opens and closes its resource handles. Caller filesystem ownership remains unchanged. Preserve appropriate source containment without claiming that every `fs.FS` is a security sandbox. Captured reads are not an atomic transaction over a concurrently changing filesystem. Definition changes require new engine construction. No watcher, background refresh, or lazy compatibility mode is added. Applications own engine replacement; prepared handles remain bound to their original engine and overlapping engines retain separate capacity pools. Request artifacts and schema preparation remain invocation work. A request can replace the output contract, so construction need not compile unused schemas. Prepared execution continues to freeze its effective resources. Environment credential lookup remains at the established execution/preparation boundary, not frozen into the configuration snapshot. Ordinary execution uses indexed ready definitions and resolved presence values. It performs no configuration discovery, parsing, inheritance traversal, or provenance analysis. Context cancellation remains cooperative at controlled boundaries; do not add detached work to pretend synchronous ConfigKit loading is instantly interruptible. ## Explicit Operator Inspection Add an API consumers can use to implement targeted CLI commands or debug output for effective configuration, contributing sources, and explanations. Retain ConfigKit inspection state with the engine's configuration snapshot and reuse its redaction and provenance facilities. Inspection is explicitly invoked and uses that snapshot without reloading files, opening resources, or contacting providers. It does not predict every runtime override, reveal execution-time credential values, or replace prepared-run details and execution observations. No provenance traversal, explanation generation, or configuration-report rendering occurs during ordinary prompt runs. Expose a read-only inspection view backed by retained ConfigKit state, with targeted path queries, source/history information, and explicit redacted effective and explanation output. Reuse suitable public ConfigKit inspection values rather than mirroring them. Do not expose mutable runtime definitions, resource capabilities merely for diagnostics, or request credentials. The scope is generic targeted inspection, not just narrow profile/prompt origin summaries. PromptKit ships no CLI and emits no automatic debug reports. Applications own presentation, access control, and disclosure; redaction does not make all prompt or configuration content safe to publish. ## Required Refactoring And Coordination - Replace profile/prompt metadata prepasses, selected-file decoding, and per-call scans with ConfigKit collection loading and immutable indexed definitions. - Remove the custom profile inheritance resolver and error-driven repository overlay stack. Do not retain an old-format compatibility engine alongside the new semantics. - Route catalog and programmatic backend definitions through ConfigKit; retire the separate backend-manifest decoder and pre-handoff registration validation. Retain backend endpoint, capacity, and provider-parameter domain validation on the final effective values. - Retain only needed discovery and message-resource adapters; remove direct YAML dependency usage once no remaining owner needs it. Preserve JSON Schema, runtime JSON-value ownership, domain validation, and execution collaborators. - Adapt maintained catalogs and PromptKit-owned definitions to the agreed keyed format and released inheritance semantics, including keyed backend assets. Preserve maintained name commitments and the intended shipped backend settings. Catalog source-policy enforcement belongs to catalog maintainers. Coordinate compatible catalog releases before consuming the changed asset format. Publish new keyed assets directly in the existing data-only catalog projects, recording the format transition rather than maintaining duplicate legacy assets or a permanent conversion adapter. Catalog maintainers select release/version handling under their own policies; old consumers must not be assumed capable of decoding the new shape. Pin the compatible released versions in PromptKit. This document requests no immediate changes in those repositories. - Keep configuration conversion, normalization, and inspection connected to ConfigKit's lifecycle instead of reconstructing effective values/history after loading. Translate once into execution-owned values with necessary copying. - Update canonical formats, consumer guidance, GoDoc, internal inventory, examples, architecture boundaries, dependencies, and OSS notices when implementation lands. ## Efficiency And Validation Expectations Target linear or near-linear work relative to actual input, output, and retained history, accounting separately for sorting, resource reads, and domain work. Acquire/parse each accepted source occurrence once, avoid decoding intermediate tiers, and index definition selection. Do not duplicate inheritance expansion or copy complete accumulated collections for every added layer. Materialized inherited data and provenance can exceed source size. Exercise real catalog shapes within ConfigKit's budgets; do not claim unconditional O(n) runtime or memory. Prefer clear ownership and straightforward indexes over global caches or elaborate optimization. Operator inspection may perform work proportional to the requested report; that work remains off the execution path. Tests should use real ConfigKit with offline sources and synthetic provider collaborators. PromptKit owns its adapter, domain, lifecycle, and execution tests, not a duplicate ConfigKit parser/graph suite. Retire tests whose only purpose was the removed loading machinery or source-policy enforcement. Exercise catalog integration through the final assembled configuration and resulting behavior. Preserve meaningful execution regressions. Representative acceptance evidence must cover: - Minimal local-backend construction and execution without elaborate configuration. - Embedded defaults plus operator and programmatic contributions, including accurate inherited relative-resource origins. - Profile inheritance, changing model/backend, canceling old relationships, and discarding unwanted settings with documented semantics. - Explicit zero/false/null behavior reaching execution, construction failures, independent snapshots, and unchanged substantive preparation/execution features. - Targeted inspection with useful redacted origins and no provenance work during ordinary runs. Use focused scaling/allocation benchmarks for large collections, shared bases, and many tiers where they expose repeated-work risks. Do not add timing-based release gates or provider-network tests. ## Migration And Completion Ship as an intentionally incompatible minor release with concrete migration guidance. Cover keyed files, `base_profile` to `extends`, reserved-key behavior, recursive maps, explicit null versus omission, changed error timing, programmatic construction, backend layering in place of registration-only restrictions, and explicit engine replacement. Explain that overriding a model does not discard lower endpoint, reasoning, provider, or inheritance settings. The end state is one shared configuration model with the old loading/resolution machinery removed, useful operator inspection, and all substantive execution workflows still available. The six previously open design choices have been approved and incorporated into the owning sections above. This is not a compatibility-preserving reinterpretation of the existing configuration engine.