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

506 lines
35 KiB
Markdown

# ConfigKit Adoption Assessment
Status: assessment aligned to released ConfigKit v0.5.0. Upstream capability
prerequisites are available; PromptKit integration and migration decisions remain
for 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, sibling inheritance, presence, and source diagnostics. PromptKit should
own definition selection, 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.
## Released ConfigKit Capabilities
ConfigKit v0.5.0 satisfies the two requested prerequisites and also implements
sibling inheritance. Adopt the released public contracts rather than waiting for
the earlier proposals to be implemented:
1. **Filesystem sources:** `NewFilesystem(label, fsys).File(name)` borrows an
`fs.FS` with reusable namespace identity. Imports and resource contexts retain
that namespace. `Result.SourceContext` and `Resolution.SourceContext` expose
passive `ResourceContext` values with `FS` and `BaseDir`.
2. **Source-backed underlays:** `LoadLayered` accepts a main `Input`
and ordered `Underlay` groups. Each group composes strictly; groups overlay
recursively from lowest to highest priority. `Input{Source: NoSource()}` omits
the main input. `Mapping(label, map[string]any)` snapshots supported built-in
scalar/list/map values with explicit presence; it does not ingest arbitrary
typed structs. Generic programmatic input is not represented as CLI overrides.
3. **Sibling inheritance:** the reserved `extends` key names one immediate sibling
mapping. Relationships resolve after precedence assembly and before typed
decoding, with inherited origins, history, and resource context preserved.
This is built-in behavior, not the opt-in/registered-collection API originally
suggested by PromptKit.
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 or inheritance pass should run after ConfigKit loading.
Use released sibling inheritance for profiles, leaving domain validation in
PromptKit. This assessment does not authorize code changes in either repository.
## Evidence And Scope
PromptKit's runtime baseline remains v0.11.2; this assessment has since received
documentation-only revisions. Updated upstream review on 2026-09-30:
- PromptKit: `12d6d80024e80c552d122a076c22429bf6f2f6c2` (v0.11.2).
- ConfigKit: `dc09959cca4e105f49ec316c6d4ba585bd2340bd` (v0.5.0), verified
against the published tag. Its clean checkout passed `go test ./...` during
the release review. This replaces the earlier v0.4.2 and uncommitted-roadmap
comparison as the upstream basis for adoption.
PromptKit evidence: [consumer workflows](../consumers/pkg-promptkit.md),
[file formats](../formats.md), [source implementation](../internal/sources.md),
[runner](../internal/runner.md), and the implementation owners identified below.
ConfigKit evidence at that release: `docs/config.md`, `docs/releases/v0.5.0.md`,
`layered.go`, `source.go`, `resource_context.go`, and ADR 0009 in the sibling
checkout. That checkout is review context, not a build dependency or required
directory layout. The released configuration contract owns exact upstream behavior;
the summaries here identify its consequences for the proposed PromptKit design.
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 | Delegate sibling graph resolution, combination, and derivation to ConfigKit's `extends`; remove the custom profile resolver |
| Backend selection and domain normalization | Retain PromptKit domain rules; use recorded application resolution for configuration transformations not already handled by structural inheritance |
| 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 |
## 3. Recommended Target Loading Model
### 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.
ConfigKit expands structural inheritance before typed defaults/decoding. Perform
any remaining domain-specific resolution through its 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. Use ConfigKit's released 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 (ConfigKit handles 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 Released Sibling 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 `extends` declaration and other
omitted settings. Diagnose and document these consequences explicitly.
Replace `base_profile` with `extends` on sibling profile mappings. A string names
one exact immediate sibling; null cancels the relationship while preserving the
child's own settings. Omission retains a lower-tier directive. There is no ancestor
scope search or cross-collection reference. Superseded references are history,
not active relationships to validate; every effective relationship resolves,
including profiles not selected for execution.
Children recursively overlay their resolved parents with the same value rules:
zero/false/empty strings and sequences/null replace, mappings combine, and `{}`
does not clear inherited keys. Inherited values count as explicit input for
presence queries and absence-based defaults, even when false, zero, or null.
Do not repeat inheritance in PromptKit's application-resolution callback. Use
`Origin.Inheritance` and retained history for explicit operator inspection.
Inherited resource references retain their declaring source's context.
Enclosing inheritance resolves before nested relationships; nested inherited
directives resolve at each destination against its siblings. Defaults and
application-derived values do not trigger another inheritance pass. Model this
deliberately in PromptKit configuration rather than promising arbitrary graph
resolution over runtime values. Partial bases must fit the typed schema and
PromptKit's validation; ConfigKit grants them no special validation exemption.
`extends` is reserved in every input mapping, including provider-parameter maps,
across all source kinds. There is no opt-in switch or ordinary-data escape in the
released contract. Audit catalog and consumer payload needs before finalizing
their format; a literal provider field with that name cannot silently pass through
the configuration loader. Do not invent an encoding workaround in this assessment.
The existing request-level override API remains a separate runtime boundary.
The feature roadmap must review its interaction with configured values without
silently subjecting runtime request data to configuration inheritance directives.
### 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` | Remove custom graph traversal, cycle detection, and zero-sentinel merging in favor of ConfigKit sibling inheritance; retain only PromptKit domain validation |
| `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.
- Delegate inheritance expansion to ConfigKit once during loading rather than
rebuilding its graph in PromptKit. Assess scaling against input, materialized
inherited values, nested destination resolution, and retained history; do not
claim unconditional O(V + E) total work from the count of profiles and edges.
ConfigKit bounds expansion and retained evidence through its existing budgets;
representative catalog sizes must fit them without new per-run processing.
- 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. Upstream Readiness And Remaining Opportunities
Filesystem sources, underlays, programmatic mappings, source contexts, and sibling
inheritance are released in v0.5.0. No additional upstream feature is currently a
demonstrated prerequisite. Context-aware loading remains a possible future request
if concrete consumers need it, not a reason to delay adoption. Existing loading
is synchronous; do not simulate cancellation with detached background work.
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. Select v0.5.0 as the assessed adoption baseline; any newer selection
needs its own review. This assessment changes neither dependencies nor licenses.
## 6. Decisions And Migration
The agreed direction now incorporates ConfigKit's v0.5.0 contracts. 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.
Adopt built-in sibling inheritance, including reserved `extends`, recursive
mapping combination, null cancellation, and inherited explicit presence. Do
not preserve a parallel PromptKit structural resolver.
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.
Use released 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.
Remaining PromptKit decisions are the exact collection/version format, catalog
migration, programmatic ergonomics, operator-inspection surface, and validation
of partial base profiles. Also settle how operators discard unwanted provider
settings or old relationships using the released null semantics without a hidden
replacement pass. Check the reserved-key impact on arbitrary provider maps. These
are integration decisions, not unresolved ConfigKit API proposals.
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 `extends` references. Convert
`base_profile` to sibling `extends`; use `extends: null` to cancel a lower-tier
relationship, not to erase all settings already supplied to the child.
- 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.
Apply those same combination rules to inherited settings. Rename ordinary
configuration keys named `extends`; examine provider maps for cases where
renaming would change their substantive meaning and resolve those explicitly.
- 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
remaining PromptKit integration decisions, and specify the target end state.
The staged implementation plan can now adopt released ConfigKit support without
waiting for upstream feature work, coordinating any catalog format releases before
their consumption. 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.