Files
promptkit/docs/roadmap/configkit-assessment.md

34 KiB

ConfigKit Adoption Assessment

Status: assessment with agreed design direction; upstream API details remain to be settled before the feature roadmap and implementation plan. No runtime changes are part of this assessment.

Goal And Recommendation

Use ConfigKit to standardize PromptKit's configuration semantics and simplify its loading machinery, improving ConfigKit where a reusable capability is justified. Preserve substantive consumer capabilities, not historical loading sequences, file syntax, or Go signatures. Document intentional breaking changes and their migration paths.

Recommend adoption through an eager, immutable definition-loading boundary. ConfigKit should own YAML interpretation, source-tier combination, strict typed decoding, presence, and source diagnostics. PromptKit should own definition identity, named profile relationships, LLM-specific rules, and execution. Do not retain the lazy loading architecture merely to minimize migration, or introduce a second generic configuration framework inside PromptKit.

The expected benefits are consistent configuration semantics for applications using both libraries and removal of repeated discovery, partial metadata parsing, lazy error arbitration, and repeated profile-chain resolution. Some of those savings come from the loading redesign rather than ConfigKit itself. ConfigKit adds ongoing value by owning the generic decoding behavior and its tests.

Prerequisite: Proposed Upstream ConfigKit Work

Design, implement, and release these two ConfigKit capabilities before the dependent PromptKit refactor. The remaining recommendations assume this upstream work; finalize their integration details against its agreed public contracts. These are selected architectural prerequisites, not a claim that adoption is technically impossible using today's reader-based API.

  1. Native fs.FS sources and source-relative context. Support embedded and caller-supplied filesystems as first-class configuration sources. Define source identity, relative path resolution, ownership, and how enabled imports and overlays operate within that filesystem. This is broadly useful for libraries bundling default configuration. Passing an opened file to today's Reader supplies bytes and a label, but does not make filesystem-relative loading native to ConfigKit; that workaround is not the target architecture.
  2. Source-backed underlays with origins and programmatic input. Adopt ConfigKit's working design: strictly compose contributions within each tier, then recursively overlay explicitly ordered tiers. Support embedded, host-file, byte/reader, and labeled programmatic sources without temporary files or YAML serialization round trips. Prefer the proposed string-keyed programmatic mappings: omitted keys convey absence; present values, including nil/null, convey explicit input. Do not require typed-value ingestion as a prerequisite.

Adopt ConfigKit's recursive combination model rather than preserving PromptKit's whole-profile shadowing or atomic provider-map replacement across source tiers. No hidden replacement pass should run after ConfigKit loading. Named inheritance is a separate optional upstream request, not part of these prerequisites.

The upstream design should show how the two capabilities work together, including source origins and efficient ownership/copying. Resolve these API questions before turning the assessment into a decision-complete PromptKit implementation plan. This assessment does not authorize code changes in either repository.

Evidence And Scope

Reviewed local baselines on 2026-09-29:

  • PromptKit: 12d6d80024e80c552d122a076c22429bf6f2f6c2 (v0.11.2).
  • ConfigKit: 67c03690181c5af8dde6be325abac241dae6732f (v0.4.2).

Design update: reviewed ConfigKit's working docs/roadmap/sources-and-layering.md with checkout HEAD 36172ed20e832b371506d6aceb02dc6c8f50f71b. The reviewed roadmap included uncommitted changes, so that commit alone does not identify the reviewed text. It remains a proposed target, not implemented behavior. The recommendations here now follow its underlay semantics and support its two open-decision recommendations: labeled programmatic mappings and direct source-context queries. Verify the final upstream contracts before preparing dependent implementation details.

PromptKit evidence: consumer workflows, file formats, source implementation, runner, and the implementation owners identified below. ConfigKit evidence: its reviewed docs/config.md, docs/roadmap/deferred.md, lifecycle.go, source.go, and ADR 0001 in the sibling checkout. That checkout is review context, not a proposed build dependency or required directory layout.

ConfigKit currently exposes Load[T] over file, byte, reader, and defaults-only sources. It supports strict decoding, presence/origin records, defaults, recorded resolution, semantic validation, explicit imports, one selected filesystem overlay, and secret handling. Its parser and generic conversion machinery are private. It has no public arbitrary layer-composition, generic inheritance, or fs.FS source API. Its deferred scope explicitly excludes several of these generalizations; an upstream enhancement requires a deliberate decision.

This is a source-and-contract assessment, not a performance benchmark or full correctness audit. It does not claim measured allocation, latency, or line-count savings. Current code and canonical contracts remain authoritative until an approved implementation changes them.

1. Capability Inventory

Preserve the ability to… Replaceable mechanics and representation
Define named, versioned prompts, inspect their declared inputs, and select a version explicitly Directory scans on each operation, YAML metadata prepasses, filename layout, constructor signatures
Use inline and file-backed message templates, variables, input helpers, session templates, roles, and cache control Timing of definition/content reads and private repository interfaces
Configure named profiles, alias/inherit another profile, and override selected settings Zero-as-absence fields, per-call chain traversal, raw YAML decoding types
Supply embedded application defaults, operator definitions, maintained catalogs, and programmatic profiles Repository-wrapper stacks and exact source-option API
Register custom/local backends, use built-ins or endpoint-only profiles, and control backend capacity Configuration DTO shapes and registry assembly order
Prepare, inspect, execute, or freeze an execution for later single-claim execution Source reloading during ordinary preparation; exact preparation error ordering
Override per-run settings, credentials, reasoning, session, and output contract; append rendered messages Public value signatures if presence or clearer configuration separation requires revision
Supply inline/file artifacts and inject artifact readers, model clients, and HTTP clients Assembly APIs; runtime collaborators need not be YAML-decodable
Validate output, use provider-native structured output, bounded repair, transport retries, cancellation, and observation Internal wiring, not the substantive execution behaviors
Receive results, usage, identities, hashes, validation outcomes, and inspectable failures Configuration error types and when definition failures appear

Preserve independent profile and prompt inspection as useful operations. They need not retain the old guarantee that engine construction has never examined other definitions. Preserve custom backend identity and capacity behavior, optional upstream credentials, and the distinction between failed generated content and operational errors. This project does not authorize silently dropping execution features to simplify the configuration layer.

Add explicit configuration inspection for consumers implementing operator-facing CLI commands or debug output. This is a new capability motivated by this adoption, not an assertion that the current prompt/profile inspection methods already provide configuration provenance.

2. Responsibility Mapping

Concern Recommended owner and disposition
YAML grammar, scalar interpretation, one-document enforcement, unknown fields, typed ranges, null legality Delegate to ConfigKit; remove corresponding PromptKit parser logic and redundant parser tests
Field presence, source coordinates, and configuration provenance Delegate to ConfigKit; retain its inspection state with the loaded snapshot for explicit operator queries, separate from execution-ready values
Operator-facing configuration inspection Provide a PromptKit consumer API reusing ConfigKit inspection facilities; applications own CLI commands, presentation, and disclosure policy
File/directory/embedded source selection and definition ID indexing Retain a small PromptKit collection loader; ConfigKit loads documents, not a prompt catalog
Configuration filesystem sources, relative imports, and generic layer origins Delegate to the prerequisite ConfigKit APIs; do not maintain parallel reader-based loading machinery
Definition discovery and relative message-content references Retain PromptKit's domain resource adapters, using ConfigKit source context and standard io/fs facilities where sufficient
Profile-source priority and combination PromptKit selects tiers; ConfigKit owns strict within-tier composition and recursive cross-tier overlay; eliminate repository fallback and whole-definition shadowing
Named profile inheritance and backend selection PromptKit owns domain relationships unless the separate inheritance proposal is adopted; integrate resolution with ConfigKit's recorded lifecycle
LLM setting bounds, role/session normalization, output rules, reserved provider fields Retain shared PromptKit domain owners; ConfigKit validation callbacks may invoke them
Definition defaults Use ConfigKit defaults where they do not erase inheritance presence; apply effective execution defaults after inheritance
Programmatic configuration Prefer labeled mapping input with explicit presence; evaluate whether typed PromptKit convenience constructors justify conversion code, without YAML round trips or zero-value inference
Runtime clients, observers, artifact readers, request data Retain normal Go injection and request APIs; do not load them through ConfigKit
Credentials Retain optional environment-name and direct request-key semantics; do not replace these with ConfigKit's required typed secret resolution
Catalog manifest, ownership, reserved names, secret-safety checks Retain the catalog adapter; reuse the common ConfigKit profile decoder
JSON Schema resources and generated-output validation Retain JSON Schema implementation; these are not application configuration documents
Application imports, CLI overrides, deployment overlays, secrets-directory bootstrap Leave with consuming applications unless a concrete PromptKit need is accepted
Generic source/decoding diagnostics Reuse ConfigKit; add only PromptKit identity/context and domain relationship diagnostics

Definition Snapshot

Create one immutable definition snapshot during engine construction. Discover the explicitly supplied sources, assemble their contributions through ConfigKit, decode the effective configuration, normalize domain values, and resolve relationships before publishing the engine. No provider call or credential availability check belongs in this phase. Publish no partially initialized engine on failure.

Prefer keyed collections, such as profiles.<name>, assembled before one typed loading lifecycle instead of independently decoding each profile and recombining the results. Multiple files can contribute to those collections; this does not require a monolithic file. Reconsider the previous one-typed-document-per-definition recommendation. Settle prompt ID/version representation and catalog format migration in the feature roadmap. Support OS directories, individual files, embedded/custom fs.FS sources, and programmatic input through the new source model; source selection and definition discovery remain PromptKit concerns, not a second composition engine.

Perform domain-specific resolution through ConfigKit's recorded lifecycle before semantic validation and result publication. Reuse its presence and provenance; do not add a generic merge/defaulting pass or reconstruct origins after loading. Runtime client assembly and resource interpretation remain outside typed decoding.

Load and freeze referenced message text with definitions. Validate static prompt structure and template syntax at loading, using the same template function setup as execution; render only when request variables and artifacts exist. Preserve source-relative content resolution and containment without expanding the threat model. A snapshot is a set of captured reads, not an atomic filesystem transaction.

Resolve each effective content reference using its contributing source's context, not the highest tier's directory. Support ConfigKit's proposed direct context query rather than a consumer-maintained filesystem registry. Composite origins must not be assigned an arbitrary directory; ambiguous or absent context needs an actionable resource error or explicit consumer-supplied context. ConfigKit does not snapshot external text: PromptKit opens it explicitly and freezes it before engine publication. Caller-owned filesystem lifetimes remain caller-owned; close resource handles acquired by PromptKit without retaining ConfigKit load handles.

Keep request artifacts and schema compilation at preparation. A request can replace the output contract, so an unused default schema should not need eager compilation. Prepared execution continues to freeze its effective resources. The snapshot covers definitions/message text, not environment values, request files, every schema file, or execution state.

Composition And Validation

Use explicit source categories in the existing useful priority order: programmatic profiles, operator source, application fallback, PromptKit-owned profiles, then external catalogs. Express these as explicit ordered tiers, not source discovery order. Within a tier, mappings compose recursively and overlapping non-mapping contributions conflict, even when equal. Disjoint contributions to the same profile may therefore combine; do not preserve a blanket duplicate-ID rejection. Across tiers, mappings overlay recursively, retaining omitted lower children. Effective prompt identities/versions must remain addressable, with an omitted version ambiguous when multiple versions exist; finalize their keyed representation without reintroducing whole-definition shadowing.

All sources undergo syntax, acquisition, and composition checks; higher tiers cannot hide those failures. Decode and validate effective values after assembly, not every intermediate tier against the final typed schema. A replaced lower value may consequently have a type that would not fit the final schema. An unused invalid effective definition still fails construction. Catalog ownership, reserved-name, and secret-safety checks remain distinct source-policy requirements, not a reason to impose intermediate typed validation on ordinary inputs.

Preserve profile templates that become usable through descendants or runtime overrides: eager loading must not require every consumer profile to be an independently runnable endpoint/model pair. Validate supplied fields and graph integrity eagerly (including missing bases and cycles), and check final execution requirements after runtime selection/overrides. Prompt default-profile references can be checked against the assembled collection; a prompt with no default remains valid for callers that supply a profile explicitly.

ConfigKit's ordering is typed defaults, source-underlay tiers, strictly composed main input, selected overlay, then CLI overrides. PromptKit's API must map its source priorities explicitly onto supported roles; do not mislabel programmatic input as CLI flags. Underlay-only loading avoids inventing a main document. Imports remain opt-in, and the named-overlay convenience need not be exposed by PromptKit merely because ConfigKit supports it.

A prompt's version is a domain identifier, not automatically a ConfigKit application-schema version. Do not configure VersionRule for prompt versions. If a separate configuration schema version is later needed, respect ConfigKit's designated main-input ownership and pre-underlay check timing; do not assume last-wins version selection across catalogs.

Source Presence And Separate Named Inheritance

Adopt ConfigKit source-layer semantics: absence retains lower input; explicit zero, false, and empty strings replace it; mappings combine recursively; empty mappings retain lower children; sequences replace as units; null explicitly replaces, subject to final schema legality. No reset/delete operator is assumed. Preserve presence through domain resolution, backend/framework default application, request overrides, and outbound request construction. Otherwise accepting temperature: 0 during decoding would accomplish nothing.

Use ConfigKit metadata for both file and programmatic input. A final Go value alone does not distinguish absent from explicit zero. Avoid eagerly defaulting profile fields in ways that erase that distinction before relationship resolution.

Provider extra_params maps combine recursively across source tiers too: {} does not clear lower keys. Retire the proposed atomic source-map replacement and null-as-unspecified conventions; do not emulate them after loading. An operator overriding only model also retains a lower base_profile declaration and other omitted settings. Diagnose and document these consequences explicitly.

Named inheritance still selects relationships between effective entries; source layering does not implement it. The optional upstream request remains pending. Finalize named-inheritance null/map semantics separately, favoring consistency with source layering rather than automatically retaining atomic maps or null-as- inherit. Any domain exception needs explicit justification. This also does not silently change the existing request-level override contract, which is a separate runtime boundary to review in the feature roadmap.

Resolve shared ancestors once per snapshot. Use recorded domain resolution to keep resulting values and origins consistent. Confirm the upstream lifecycle can express required relationship provenance; do not claim generic layer history already explains named inheritance or invent a parallel audit framework.

Reloading, Errors, And Application Integration

Later definition edits take effect through a newly constructed engine. Do not add watchers, mutable registry reloads, or a second lazy compatibility mode. Applications choose how to swap engines and let in-flight work finish. Old prepared handles remain associated with their original engine. Simultaneously active engines have separate backend capacity pools; migration guidance must not imply a global limit across a reload overlap.

Return configuration failures from construction with file/path/location and useful definition identity where available. Recommend preserving ConfigKit's public LoadError through wrapping for errors.As, together with a PromptKit configuration category; do not copy its entire diagnostic API into the facade. Domain-only relationship failures remain PromptKit errors with relevant source locations. Start with deterministic fail-fast loading across files and ConfigKit's existing multi-diagnostic behavior within a load, rather than inventing a batch diagnostic subsystem. Do not expose raw credentials or add implicit logging.

Runtime failures continue to distinguish invalid requests, missing selections, rendering/artifact/schema errors, provider/transport errors, capacity rejection, and content-validation results. Cancellation remains effective at PromptKit-controlled boundaries; ConfigKit's current synchronous Load has no context argument, so do not promise interruption inside it or create goroutines to simulate that guarantee.

Applications using ConfigKit can present the same underlying loading diagnostics for their application settings and PromptKit files. They can also translate application-owned typed settings into PromptKit profiles/backends. Do not require applications to encode Go clients into YAML or adopt ConfigKit merely to call PromptKit's runtime API. The operator-inspection capability below supplies the concrete consumer purpose for exposing effective configuration and its provenance.

Explicit Configuration Inspection

Provide a consumer-facing API for inspecting effective configuration and its provenance so applications can implement targeted CLI commands or debug output. Keep three activities distinct:

  • Construction: load and resolve configuration, retain ConfigKit's provenance and inspection state, and publish execution-ready definitions. Resolve any presence and origin information needed for definition construction here.
  • Ordinary execution: use the ready definitions directly. Do not analyze configuration provenance, traverse origin/history records, reconstruct inheritance explanations, or render effective-configuration reports as part of a prompt run. Carry execution-relevant presence explicitly in resolved values rather than querying configuration metadata during each run.
  • Explicit inspection: query effective settings and their contributing sources or explanations only when a consumer invokes the inspection API. Inspection uses the same loaded configuration snapshot as the engine; it does not reread configuration files, open referenced resources, or contact providers.

Reuse ConfigKit's inspection and redaction facilities rather than maintaining a second provenance system. The API should make targeted queries practical; exact signatures, query scope, and safe result ownership belong in the feature roadmap. Do not imply that configuration inspection predicts all runtime request overrides or reveals the values of execution-time credentials. Existing prompt/profile inspection, prepared-run details, and execution observations have distinct purposes; configuration inspection does not replace them or add provenance to run events.

Applications decide whether and how to expose inspection through operator tools. PromptKit adds no CLI, implicit debug logging, or automatic explanation output. Redacted configuration can still contain sensitive application content, so callers retain responsibility for access control and disclosure. Retention has a memory cost, but explanation generation and provenance analysis stay off the run path.

4. Simplification Accounting

Current implementation Expected disposition
internal/profile/filesystem_repository.go: metadata scans, selected strict decode, stream-end checks, malformed-file selection arbitration Replace with source acquisition, ConfigKit assembly/decoding, and indexed effective values; remove the metadata prepass and per-lookup filesystem path
internal/promptdef/filesystem_repository.go: metadata selection and repeated decoding/content opening Replace with eager prompt loads and an ID/version index; keep domain normalization and contained content reading
Profile filesystem, fs.FS, eager, memory, and overlay repository variants Collapse loading into source adapters plus immutable collections; preserve only interfaces that still serve a real boundary
internal/profile/resolving_repository.go Replace per-operation traversal and zero-sentinel merging with once-per-snapshot presence-aware typed resolution; graph logic remains
internal/engine raw repository-stack assembly Replace with ConfigKit source tiers and one effective typed collection; engine capacity/client assembly remains
internal/catalog profile metadata extraction Obtain explicit field information from ConfigKit; retain manifests, ownership, namespace, connection-metadata and secret checks
internal/filecatalog Retain/reduce discovery and containment helpers actually needed by the eager loader; do not claim the entire package disappears
internal/domain source YAML tags and runtime/source coupling Separate configuration DTOs from execution values where presence requires it; reuse domain validation rather than duplicating it
Direct gopkg.in/yaml.v3 use for definition loading Remove once all such consumers migrate; ConfigKit brings its own private YAML dependency

New integration work is real: collection DTOs, ConfigKit calls and error wrapping, source-context access, collection indexing, programmatic mapping ergonomics, and conversion to runtime definitions. Catalog documents may need new keyed shapes; do not hide that migration behind a permanent second loader. Some defensive copies remain necessary at public/injected-client boundaries; ConfigKit's detached load result is not permission to expose shared engine maps. internal/jsonvalue still serves programmatic values, request parameters, and prepared schema ownership, so adoption does not eliminate it.

Maintenance savings depend on actually deleting the old lazy paths and their special-case tests. Move generic YAML/scalar behavior coverage to ConfigKit's ownership; PromptKit retains representative adapter tests plus domain, precedence, snapshot, inheritance, embedded-source, error, and execution integration tests. Do not duplicate ConfigKit's entire parser suite or discard execution regression coverage because construction fixtures need migration.

Runtime benefit: ordinary runs no longer rediscover definition directories, redecode definitions, reread template text, or traverse inheritance chains. Cost: construction loads even unused definitions and retains their text and resolved values. Retain ConfigKit inspection state needed by the explicit operator API without duplicating its history in runtime definitions or per-run values. These are reasoned tradeoffs, not measured performance claims. Adoption is not justified by the decoder replacement alone.

Algorithmic Efficiency

Efficiency is an explicit design criterion for both the upstream work and this shared-library refactor. Prefer optimal or near-optimal algorithms relative to input and produced-data size, not a blanket O(n) claim with an undefined n.

  • Acquire/parse each accepted source occurrence once, assemble input, and run one typed loading lifecycle rather than decoding intermediate tiers. Reuse captured content instead of reparsing it for metadata, selection, and validation.
  • Build identity indexes in one pass, with expected constant-time map lookup. Do not scan whole collections for every lookup or precedence decision.
  • Process inheritance graph structure in O(V + E), where V is the number of profiles and E the inheritance edges. Resolve shared ancestors once. Account separately for the size of materialized settings and retained origins; copying large inherited maps to many independent results necessarily costs more than V.
  • Avoid whole-collection copying per layer, repeated serialization, and repeated prefix/history traversal. Analyze layer processing against total input nodes and produced values/provenance, including intentionally retained history.
  • Keep configuration discovery, decoding, and provenance analysis out of ordinary execution. Perform explanation work only on explicit inspection calls. Copy only where ownership requires it; do not trade caller isolation for speed.

These are design targets, not promised complexity for every operation. Sorting for deterministic discovery may require O(F log F) for F files, and processing message text costs work proportional to its bytes. Construction time, retained memory, and frequent-call costs all matter. Prefer straightforward indexes and clear immutable ownership over speculative global caches or intricate optimizers. The implementation plan should include focused benchmarks for consequential repeated-work risks, such as shared-ancestor profiles and many layers, rather than machine-dependent timing gates or benchmarks for every helper.

5. Additional Upstream Opportunities

Native filesystem sources and public layered loading with origins are the prerequisites described near the beginning, not optional follow-ups. The following remain optional and do not block adoption unless the upstream design establishes a concrete dependency:

Candidate Recommendation and tradeoff
Generic named configuration inheritance Requested separately in ConfigKit's docs/roadmap/feature-request-promptkit-inheritance.md, primarily for shared semantics across consumers. ConfigKit decides whether to adopt it; PromptKit can retain a small domain resolver if declined. Presence-aware source layering belongs to the prerequisite work, not this optional proposal.
Context-aware loading Optional for reusable cancellable construction if large-source consumers need it. Promise cooperative cancellation only; no detached reads or instant interruption of arbitrary readers.

Do not propose a public raw AST, permissive identity-only decoder, or dynamic subtree conversion solely to preserve PromptKit's current scanning design. Do not upstream backend/model selection, credential timing for inference, profile catalog reservations, or prompt-template functions.

ConfigKit and PromptKit both declare LGPL-3.0-or-later. Adoption must still update dependency notices under the OSS policy and inspect the exact selected release and its transitive notices. Their current Go minimums do not require a PromptKit toolchain increase. Use a released module dependency, not a sibling-directory replacement. This assessment proposes upstream work, but makes no upstream edits or licensing change.

6. Decisions And Migration

The agreed direction now incorporates ConfigKit's working roadmap. This supersedes the earlier recommendations for independently typed documents, whole-definition shadowing, intermediate typed validation, and atomic maps/null-as-unspecified at the source boundary.

  1. Loading lifetime and failure scope. Keep eager construction and frozen definitions/content. Syntax/acquisition/composition failures remain unmaskable; typed and domain validation apply to effective values. A separate reusable public snapshot lifecycle remains possible but is not currently needed.
  2. Source organization. Prefer keyed collections composed across files and tiers before typed loading. Settle exact profile and prompt/version shapes, source-role mapping, and catalog migration in the feature roadmap. Independent typed loads followed by custom combination are not the selected direction.
  3. Presence and relationships. Accept recursive source-tier overlay, retained children for empty mappings, explicit null replacement, and effective metadata. Named inheritance remains separate pending the upstream decision; settle its domain semantics before implementation rather than assuming either automatic equivalence or an exception to ConfigKit's rules.
  4. Diagnostic boundary. Keep wrapping ConfigKit's public loading errors rather than mirroring them. Retain actionable domain relationship and resource errors without duplicating ConfigKit's generic diagnostic/provenance system.
  5. Operator inspection. Expose effective configuration and provenance through an explicit consumer API backed by the engine's loaded snapshot. Retain the required ConfigKit inspection state at construction; never analyze it during ordinary prompt execution. Finalize targeted query shapes and ownership in the feature roadmap, with presentation remaining application-owned.

Support the upstream recommendations for labeled mapping-based programmatic input and direct filesystem resource-context queries. If real consumer examples show mapping construction to be repetitive, consider small typed PromptKit conveniences with explicit presence rather than requiring an upstream typed-ingestion API. Final upstream signatures and ownership details remain open dependencies of the feature roadmap, not implemented guarantees. Resolve the named-inheritance direction there as well; a PromptKit-owned resolver remains viable if ConfigKit declines or defers that optional request.

Expected consumer migration:

  • Update definitions for ConfigKit's strict scalar rules, rejected YAML anchors/aliases/tags, input limits, and null/type checks. Quote prompt version strings rather than introducing a special numeric-version conversion merely for historical YAML coercion.
  • Move standalone definitions into the agreed keyed contribution format. Review same-name contributions: disjoint fields within a tier can combine, and higher tiers retain omitted lower fields, including base_profile references.
  • Review zero/false/empty/null values explicitly. Provider maps merge across tiers, {} does not clear them, and null replaces rather than means omission. Use labeled programmatic mappings or approved presence-aware conveniences. Document the separately selected inheritance semantics when settled.
  • Handle effective-definition errors at construction, fix syntax/composition failures even in overridden inputs, and deliberately rebuild/swap engines after definition changes.
  • Keep runtime credential lookup optional, avoid baking resolved secrets into definition snapshots, and preserve request-scoped key overrides.
  • Update maintained catalog data for collection shapes and any incompatible syntax; coordinate catalog releases before the PromptKit dependency update. Preserve maintained profile names and catalog ownership rules, not every old scalar spelling. Do not validate live provider/model availability.
  • Update error inspection, constructor/source options, and programmatic profile literals as required. Keep representative preparation, execution, inspection, custom backend, fallback, and embedded workflows in the migration guidance.

The subsequent feature roadmap should carry forward these choices, resolve the upstream API details, and specify the target end state. The staged implementation plan must sequence the prerequisite ConfigKit releases before dependent PromptKit work, then cover deletions/replacements, contract tests, canonical documentation, examples, attribution, and minor-release migration notes. Neither document should become a reason to preserve obsolete compatibility machinery.