506 lines
35 KiB
Markdown
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.
|