Retire unselected collection configuration proposals
This commit is contained in:
@@ -1,372 +0,0 @@
|
||||
# Proposal 1: Namespaced Collections With Current ConfigKit
|
||||
|
||||
Status: proposed PromptKit configuration standard; not implemented or accepted.
|
||||
This proposal addresses the pending configuration decision in the
|
||||
[namespace and collection roadmap](namespaces.md). It requires PromptKit changes
|
||||
but no ConfigKit extension. Proposal 2, which may assume upstream changes, is
|
||||
outside this document.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Keep the existing top-level `backends`, `profiles`, and `prompts` mappings, and
|
||||
use fully qualified resource IDs as their actual YAML keys. Add a `collections`
|
||||
mapping keyed by namespace for release metadata. The application's main input
|
||||
owns `version: 1`; reusable collection contributions omit that top-level field.
|
||||
|
||||
Compose independently maintained peer collections in one ConfigKit underlay
|
||||
group. Put intentional application/operator overrides in later groups or the
|
||||
main input. This uses ConfigKit's distinction between strict composition and
|
||||
explicit precedence to protect independent contributions while retaining
|
||||
ordinary configuration customization.
|
||||
|
||||
Namespace identity exists in the configuration tree before composition. A
|
||||
separate `id` field inside an otherwise unqualified prompt definition would be
|
||||
too late: ConfigKit merges mapping keys before PromptKit interprets definitions.
|
||||
|
||||
## Reviewed Baseline And Evidence
|
||||
|
||||
Reviewed the local `../ConfigKit` checkout at commit
|
||||
`6fffde4af8f31f99d3ee295c426eb3234cb0fb77` (v0.7.1), the version selected by
|
||||
PromptKit. The governing upstream sources are its
|
||||
[configuration contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.1/docs/config.md)
|
||||
and [composition/overlay decision](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.1/docs/adr/0001-separate-composition-and-overlay.md).
|
||||
Implementation evidence includes `internal/engine/compose_test.go`,
|
||||
`internal/engine/load_request_test.go`, `internal/engine/imports_test.go`, and
|
||||
the public `VersionRule` and `LoadLayered` declarations in that checkout.
|
||||
|
||||
The relevant current rules are:
|
||||
|
||||
| ConfigKit behavior | Consequence for this proposal |
|
||||
| --- | --- |
|
||||
| Within a composition group, mappings combine recursively; every other overlapping pair conflicts, even equal scalars | Distinct qualified keys coexist; repeated metadata versions or message sequences conflict within the group |
|
||||
| Between underlay groups, later values overlay earlier ones; main has higher precedence | Directory order must not accidentally become collection precedence; intentional overrides are separate layers |
|
||||
| Overlay mappings combine recursively; scalars, sequences, and null replace lower values | An override can replace a setting or message sequence without replacing the entire prompt |
|
||||
| Syntax and strict-composition failures happen before final domain validation | A higher layer cannot repair a conflicting peer group |
|
||||
| The configured specification-version path belongs to main; underlays and imported fragments cannot claim it | There is one assembled-configuration specification declaration, not independently checked collection headers |
|
||||
| Sibling `extends` resolves after composition and precedence | Fully qualified profile keys work as exact cross-collection inheritance references |
|
||||
| Defaults, typed decoding, resolution, and semantic validation operate on final assembled values | PromptKit need not validate each collection separately |
|
||||
| Source origins retain resource context and inspection history | File-backed content and explicit provenance inspection can retain existing behavior |
|
||||
|
||||
PromptKit already provides directory and embedded-source helpers, and its
|
||||
configuration adapter calls `configkit.LoadLayered` once. Its current document
|
||||
schema only exposes `backends`, `profiles`, and `prompts`; this proposal adds
|
||||
version and metadata fields rather than claiming they work today. The
|
||||
[current format reference](../formats.md) remains authoritative until adoption.
|
||||
|
||||
## Proposed Document Shape
|
||||
|
||||
The effective configuration has these application fields. Source documents may
|
||||
also use supported ConfigKit directives, which ConfigKit consumes before the
|
||||
application handoff:
|
||||
|
||||
| Field | Proposed meaning |
|
||||
| --- | --- |
|
||||
| `version` | PromptKit configuration/collection specification identifier, owned by the main input |
|
||||
| `collections` | Optional mapping from namespace to collection release metadata |
|
||||
| `backends` | Existing backend definitions, keyed by exact resource ID |
|
||||
| `profiles` | Existing profile definitions, keyed by exact resource ID |
|
||||
| `prompts` | Existing prompt definitions, keyed first by exact resource ID and then by prompt version |
|
||||
|
||||
The namespace roadmap's accepted grammar applies to resource keys: either an
|
||||
unqualified ID or exactly `namespace/local-name`. Neither qualified component
|
||||
contains `/`; dots remain available within local names. Published collections
|
||||
use qualified keys. Unqualified application definitions remain supported.
|
||||
|
||||
Keep IDs in mapping keys, including the prompt's outer key; do not introduce
|
||||
another embedded `id` or `namespace` field in each definition. Collection
|
||||
metadata does not prefix or rewrite keys. Filenames and directory names have
|
||||
no effect on identity. Namespace comparison and references remain exact.
|
||||
|
||||
The following compact contribution could be supplied by a provider collection.
|
||||
The endpoint and model are synthetic configuration examples, not live targets:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
provider:
|
||||
version: "2026.10.14"
|
||||
backends:
|
||||
provider/default:
|
||||
endpoint: https://inference.example.invalid/v1
|
||||
profiles:
|
||||
provider/brief:
|
||||
backend: provider/default
|
||||
model: vendor/example-model
|
||||
temperature: 0.2
|
||||
```
|
||||
|
||||
Two independently maintained application collections can then supply the same
|
||||
local prompt name without colliding:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
weatherreporter:
|
||||
version: "2.4.0"
|
||||
prompts:
|
||||
weatherreporter/alerts.summarize:
|
||||
"1":
|
||||
default_profile: provider/brief
|
||||
messages:
|
||||
- role: user
|
||||
content: Summarize the weather alerts.
|
||||
output:
|
||||
format: text
|
||||
validation_mode: none
|
||||
```
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
homewatch:
|
||||
version: "3.1.0"
|
||||
prompts:
|
||||
homewatch/alerts.summarize:
|
||||
"1":
|
||||
default_profile: provider/brief
|
||||
messages:
|
||||
- role: user
|
||||
content: Summarize the household alerts.
|
||||
output:
|
||||
format: text
|
||||
validation_mode: none
|
||||
```
|
||||
|
||||
ConfigKit sees separate keys under `prompts`. It never needs to understand
|
||||
PromptKit namespaces to preserve both definitions. The quoted `"1"` keys are
|
||||
individual prompt versions, unrelated to the main specification version or the
|
||||
collection release strings.
|
||||
|
||||
## Specification And Collection Versions
|
||||
|
||||
Configure ConfigKit's existing `VersionRule` at `configkit.Keys("version")`.
|
||||
Recommend requiring an explicit supported value on the selected main input for
|
||||
this new standard: canonical YAML is `version: 1`. ConfigKit exposes both integer
|
||||
`1` and string `"1"` as version text `1`; accept both, while documenting the
|
||||
integer spelling. Reject absent, null, and unsupported versions through the
|
||||
configured checker. These are proposed PromptKit format choices, implemented
|
||||
through ConfigKit's supported callback, not a separate input-scanning pass.
|
||||
|
||||
A minimal main input is:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
```
|
||||
|
||||
Programmatic applications can supply the same main input with `configkit.Mapping`.
|
||||
Do not infer the specification from a directory name or collection release, strip
|
||||
version fields from fragments, or silently inject a version to hide a missing
|
||||
declaration. Requiring main instead of accepting an omitted main is an additional
|
||||
explicit migration cost of this proposal.
|
||||
|
||||
Reusable collection files, including a collection's root metadata file, omit
|
||||
top-level `version`. So do operator underlays and imported fragments. ConfigKit
|
||||
protects the configured version path even if a repeated value would equal `1`.
|
||||
The version checker is invoked by ConfigKit once, at its normal point before
|
||||
underlay assembly; it selects the contract for the complete configuration.
|
||||
|
||||
For collection metadata, propose an ordinary optional `collections` mapping:
|
||||
|
||||
- Its keys are exact nonblank namespace names without `/`.
|
||||
- Each effective entry is a non-null mapping with a required nonblank string
|
||||
`version`. Quote collection release identifiers; this nested field does not
|
||||
receive ConfigKit's special integer-to-string handling for top-level `version`.
|
||||
- Release strings are descriptive publisher identifiers, not executable
|
||||
dependency constraints or implicit precedence. No SemVer ordering is needed.
|
||||
- An omitted, null, or empty top-level `collections` mapping means no declared
|
||||
collection metadata. Null individual entries are invalid final descriptors;
|
||||
null is not a new per-entry deletion operator.
|
||||
|
||||
Validate this metadata only in final effective values. Do not require a metadata
|
||||
entry for every resource namespace or require every metadata entry to have
|
||||
resources. This lets ordinary application configuration add definitions or
|
||||
overrides without fabricating a collection release. Collection publishing
|
||||
guidance recommends declaring its own namespace and version, but PromptKit
|
||||
does not audit which source file originally contributed a resource.
|
||||
|
||||
## Source Selection And Layering
|
||||
|
||||
Recommend this caller-selected assembly:
|
||||
|
||||
| Tier | Contents | Relationship |
|
||||
| --- | --- | --- |
|
||||
| First underlay group | All selected peer collection inputs | Strict composition across the entire group |
|
||||
| Later underlay groups, if selected | Application defaults or operator override documents, in caller-chosen priority order | Strict within each group; later groups overlay earlier groups |
|
||||
| Main input | Specification declaration and optional highest-priority local settings | Overlays the underlays |
|
||||
|
||||
These are integration guidance, not a new enforced source policy. The application
|
||||
still selects ConfigKit groups and precedence explicitly. In particular, separate
|
||||
directories do not each require their own underlay tier. Append their discovered
|
||||
inputs into one group when they are independent peer libraries. Putting each
|
||||
directory into a successive group intentionally enables later overrides.
|
||||
|
||||
An illustrative caller arrangement using existing source APIs is:
|
||||
|
||||
```go
|
||||
var peers []configkit.Input
|
||||
for _, directory := range collectionDirectories {
|
||||
inputs, err := promptkit.DirectoryInputs(directory)
|
||||
if err != nil { return err }
|
||||
peers = append(peers, inputs...)
|
||||
}
|
||||
main := configkit.Input{Source: configkit.File(applicationConfigFile)}
|
||||
sources := promptkit.ConfigurationSources{
|
||||
Underlays: []configkit.Underlay{{Inputs: peers}},
|
||||
Main: &main,
|
||||
}
|
||||
// Pass sources to NewEngine after the proposed document schema is implemented.
|
||||
```
|
||||
|
||||
The helpers already supply filesystem context, recursively select YAML, and
|
||||
leave imports disabled. An operator may install a collection with an ordinary
|
||||
`collection.yml` metadata contribution and definition files in subdirectories.
|
||||
That filename is a recommended packaging convention, not a special loader
|
||||
instruction. All selected YAML files participate normally; resource files should
|
||||
be outside that scan or use suitable non-configuration formats.
|
||||
|
||||
For explicit imports instead, select only collection entry-point files, enable
|
||||
imports on those inputs, and let ConfigKit traverse their fragments. Do not both
|
||||
recursively select all files and import those same files in the same group:
|
||||
ConfigKit rejects repeated sources. Imports remain root-contained, relative,
|
||||
opt-in paths/globs; they neither fetch repositories nor establish precedence.
|
||||
Each directory input can have its own filesystem root, so peers need not share
|
||||
an installation directory.
|
||||
|
||||
Importing all peers from main is also possible under ConfigKit's rules, but
|
||||
main's own definitions and its imports then compose strictly. A main document
|
||||
cannot override something in its own import graph. The recommended underlay
|
||||
arrangement keeps main available for ordinary application overrides without
|
||||
requiring a selected-overlay API addition to PromptKit.
|
||||
|
||||
## Collisions, Partial Contributions, And Overrides
|
||||
|
||||
| Contributions | Current ConfigKit outcome |
|
||||
| --- | --- |
|
||||
| `weatherreporter/alerts.summarize` and `homewatch/alerts.summarize` | Both definitions remain |
|
||||
| Same qualified prompt ID, different prompt-version keys | Both versions remain; PromptKit's existing version selection applies |
|
||||
| Same ID/version, disjoint definition fields in one group | Fields compose into one definition |
|
||||
| Same ID/version, overlapping message sequences in one group | `compose.conflict`, even if the sequences are identical |
|
||||
| Same `collections.<namespace>.version` in two peer inputs | `compose.conflict`, even if release strings are equal |
|
||||
| Same namespace with disjoint metadata/resource contributions | Contributions can compose; there is no namespace-ownership error |
|
||||
| Same qualified ID or collection metadata in a later layer | Ordinary recursive overlay semantics apply |
|
||||
|
||||
This does not promise that every repeated resource ID or collection namespace
|
||||
is fatal. ConfigKit permits disjoint mapping contributions by design. Namespace
|
||||
qualification avoids accidental *cross-namespace* collisions; strict grouping
|
||||
detects conflicting leaves among peers. Deliberately sharing an exact key in
|
||||
different precedence layers still allows overrides.
|
||||
|
||||
For example, main can override only the selected profile's temperature:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
profiles:
|
||||
provider/brief:
|
||||
temperature: 0.1
|
||||
```
|
||||
|
||||
The lower backend and model remain. Replacing `messages` would replace the
|
||||
entire sequence, not append messages. An empty mapping does not clear inherited
|
||||
children. Explicit null retains existing PromptKit field-specific meanings;
|
||||
this proposal adds no generic delete or replace-whole-resource directive.
|
||||
|
||||
Do not inspect provenance to reject a higher-priority metadata edit, or declare
|
||||
that a collection namespace is locked to one input. Provenance is for explicit
|
||||
operator explanation. Final domain validation can reject an invalid resulting
|
||||
profile or descriptor, but cannot resurrect or reject displaced source values.
|
||||
|
||||
## References, Inheritance, And Resources
|
||||
|
||||
Stored references remain exact IDs. A collection prompt can select
|
||||
`provider/brief`; a profile can inherit `provider/brief` by writing that exact
|
||||
key as `extends`. Profile mappings remain siblings under `profiles`, so this
|
||||
uses ConfigKit's existing inheritance without moving definitions into nested
|
||||
collection containers. A consumer's selected namespace never rebinds those
|
||||
stored references. Provider `model` strings remain unchanged and may contain `/`.
|
||||
|
||||
Prompt versions remain an inner mapping. ConfigKit's sibling inheritance is
|
||||
generic, but it does not make another prompt's outer ID a sibling of an inner
|
||||
version definition. This proposal introduces no cross-prompt reference resolver.
|
||||
|
||||
Keep existing resource semantics: ConfigKit records the effective field's origin
|
||||
and source context, and PromptKit uses that context for file-backed prompt
|
||||
content. Do not derive content paths from namespaces or a collection metadata
|
||||
filename. Schema roots and runtime artifacts retain their existing separately
|
||||
configured behavior; a metadata file does not automatically mount schemas or
|
||||
change their resource resolution. Moving to configuration collections must not
|
||||
claim broader resource portability than those contracts provide.
|
||||
|
||||
## Collection Inventory
|
||||
|
||||
Propose a public `ListCollections` operation returning detached descriptors from
|
||||
the engine's captured effective metadata. Exact Go names and signatures remain
|
||||
to be chosen. Each descriptor contains namespace and declared collection release
|
||||
version. Expose the effective specification version once at engine/configuration
|
||||
level, not as a falsely independently checked version on each collection.
|
||||
|
||||
An absent metadata map returns no collection descriptors. Sort by namespace for
|
||||
stable inspection. Report resources separately through the accepted namespace
|
||||
listing/filter APIs; unregistered namespaces can exist there without fabricated
|
||||
collection versions. A metadata-only declaration can appear in collection
|
||||
inventory even when no resources remain under that namespace.
|
||||
|
||||
This API means "effective declared collections," not "every manifest ever
|
||||
loaded" or "verified installed package versions." Metadata and resources can
|
||||
be changed by later layers. A declared release does not certify that all effective
|
||||
definitions are identical to a publisher's release. ConfigKit inspection explains
|
||||
the sources and edits; the domain API does not replay history or reread files.
|
||||
|
||||
## PromptKit Changes And Deliberate Limits
|
||||
|
||||
Adoption would add the version field/checker and collection metadata schema,
|
||||
final-value validation, captured inventory, and the public collection API. It
|
||||
would also implement the accepted scoped lookup and discovery behavior and
|
||||
remove automatically bundled catalogs and built-in profiles, as tracked in the
|
||||
parent roadmap. Update canonical contracts and migration guidance only when
|
||||
those changes land. Existing documents with no main specification declaration
|
||||
would need an explicit migration under the proposed version policy.
|
||||
|
||||
There is no ConfigKit change, per-collection loading/validation pass, source-level
|
||||
namespace registry, key-rewriting stage, or automatic configuration installation.
|
||||
Definitions retain their qualified keys throughout assembly. Invalid effective
|
||||
domain values are PromptKit's responsibility; composition, imports, inheritance,
|
||||
and version-path protection remain ConfigKit's responsibility under
|
||||
[ADR 0001](../adr/0001-configuration-boundary.md).
|
||||
|
||||
The main limitation is independent specification compatibility: a reusable
|
||||
collection cannot carry its own protected top-level `version: 1` when imported
|
||||
or used as an underlay. Publishers/operators must select configuration compatible
|
||||
with the main standard. Strict decoding catches unsupported surviving fields,
|
||||
but it is not an independent compatibility check for each collection release.
|
||||
This is the principal issue to compare with proposal 2.
|
||||
|
||||
## Validation And Review Criteria
|
||||
|
||||
Review verification on 2026-10-14: the focused ConfigKit composition, grouped
|
||||
loading, and import-version tests passed in the local checkout. A temporary
|
||||
offline consumer using that checkout also loaded the five YAML examples above
|
||||
through a prospective document schema and verified distinct identities, equal
|
||||
and unequal peer conflicts, disjoint contributions, main overrides, atomic
|
||||
sequence replacement, main/underlay/import version ownership, and qualified
|
||||
inheritance. This establishes feasibility with current ConfigKit; it does not
|
||||
implement the proposed PromptKit schema or inventory API. No temporary harness
|
||||
or module replacement is part of either repository.
|
||||
|
||||
Review this proposal against these observable cases:
|
||||
|
||||
- Two collections using the same local prompt name survive composition under
|
||||
distinct qualified keys.
|
||||
- Equal and unequal overlapping metadata versions fail in one peer group;
|
||||
disjoint contributions compose, and later metadata overrides remain allowed.
|
||||
- Main overrides one profile field while preserving other fields; sequence
|
||||
overrides replace whole sequences.
|
||||
- A strict peer conflict cannot be hidden by a higher layer.
|
||||
- Main `version: 1` succeeds, while omitted/null/unsupported versions fail the
|
||||
proposed checker and imported/underlay declarations fail ConfigKit's existing
|
||||
version ownership checks.
|
||||
- Fully qualified inheritance resolves through the assembled sibling mappings;
|
||||
file-backed content retains its declaring source's context.
|
||||
- Inventory reflects final metadata and remains captured when source files
|
||||
change; resource namespace discovery does not require a metadata declaration.
|
||||
|
||||
The configuration schema, explicit-version requirement, metadata null rules,
|
||||
inventory shape, and recommended peer-group layout are proposal choices to
|
||||
review. They do not resolve the parent roadmap's decision 5 merely by being
|
||||
written here.
|
||||
@@ -1,434 +0,0 @@
|
||||
# Proposal 2: Namespaced Collections As Identified Records
|
||||
|
||||
Status: proposed alternative; not implemented or accepted. This is a middle
|
||||
ground between [proposal 1](configuration-collections-current-configkit.md),
|
||||
which uses current ConfigKit, and
|
||||
[proposal 3](configuration-collections-mounted-fragments.md), which changes
|
||||
source placement and document organization. Proposal 3 also adopts the later
|
||||
requirement for one installed definition per prompt and an optional version;
|
||||
this proposal retains versioned record identities for comparison. The parent
|
||||
[namespace and collection roadmap](namespaces.md) retains the accepted product
|
||||
decisions and the pending configuration decision.
|
||||
|
||||
## Recommendation And Scope
|
||||
|
||||
Represent prompts, profiles, and backends as sequences of records with explicit
|
||||
identity fields. Prefer separate `namespace` and local `id` fields. Ask ConfigKit
|
||||
to support opt-in, application-declared identity rules at selected configuration
|
||||
paths, so those records compose and overlay by identity rather than position.
|
||||
|
||||
The extension is one cohesive capability: identified record sequences, including
|
||||
their strict composition, overlay, inheritance, and provenance behavior. It is
|
||||
not a general user-defined merge framework. ConfigKit continues to own the
|
||||
complete assembly process and hands PromptKit one final resolved configuration.
|
||||
|
||||
Keep the root `prompts:`, `profiles:`, and `backends:` keys. Keep collection
|
||||
metadata as the ordinary namespace-keyed mapping from proposal 1. Keep the main
|
||||
input's specification declaration and the existing source/layer model. This
|
||||
proposal does not add bare single-record files, source mounting, implicit
|
||||
namespace injection, or per-import specification checking. Those are separate
|
||||
questions for proposal 3.
|
||||
|
||||
## Current Baseline And Required Extension
|
||||
|
||||
The reviewed ConfigKit baseline remains v0.7.1, local checkout commit
|
||||
`6fffde4af8f31f99d3ee295c426eb3234cb0fb77`. Its
|
||||
[configuration contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.1/docs/config.md)
|
||||
and the implementation/tests reviewed for proposal 1 establish that:
|
||||
|
||||
- Sequences are atomic: overlapping sequences conflict during strict composition
|
||||
and replace one another across precedence layers.
|
||||
- ConfigKit can already decode a single sequence of mappings into application
|
||||
records. It does not currently use their fields as merge identities.
|
||||
- `extends` currently identifies immediate mapping siblings. A sequence-element
|
||||
mapping cannot establish its own sibling relationship, and mapping-valued
|
||||
`extends` is not a supported reference form.
|
||||
- Final decoding, application resolution, and semantic validation happen after
|
||||
configuration assembly and inheritance.
|
||||
|
||||
Consequently, changing PromptKit's document structs alone would not implement
|
||||
this proposal. Concatenating sequences in PromptKit or converting each source
|
||||
to keyed mappings before calling ConfigKit would violate the chosen boundary.
|
||||
|
||||
## Proposed Authoring Format
|
||||
|
||||
Each prompt record describes one prompt version, without a nested version-key
|
||||
mapping. Use explicit strings for identity fields:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
weatherreporter:
|
||||
version: "2.4.0"
|
||||
prompts:
|
||||
- namespace: weatherreporter
|
||||
id: summarize.alerts
|
||||
version: "1"
|
||||
default_profile: openrouter/gemini-flash-latest
|
||||
messages:
|
||||
- role: user
|
||||
content: Summarize the weather alerts.
|
||||
output:
|
||||
format: text
|
||||
validation_mode: none
|
||||
```
|
||||
|
||||
A second collection can use the same local ID without colliding:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
homewatch:
|
||||
version: "3.1.0"
|
||||
prompts:
|
||||
- namespace: homewatch
|
||||
id: summarize.alerts
|
||||
version: "1"
|
||||
default_profile: openrouter/gemini-flash-latest
|
||||
messages:
|
||||
- role: user
|
||||
content: Summarize the household alerts.
|
||||
output:
|
||||
format: text
|
||||
validation_mode: none
|
||||
```
|
||||
|
||||
The profile name is an illustrative configured reference, not a statement about
|
||||
current provider inventory. A synthetic provider contribution shows the same
|
||||
record shape for backends and profiles:
|
||||
|
||||
```yaml
|
||||
collections:
|
||||
provider:
|
||||
version: "2026.10.14"
|
||||
backends:
|
||||
- namespace: provider
|
||||
id: default
|
||||
endpoint: https://inference.example.invalid/v1
|
||||
profiles:
|
||||
- namespace: provider
|
||||
id: brief
|
||||
backend: provider/default
|
||||
model: vendor/example-model
|
||||
temperature: 0.2
|
||||
```
|
||||
|
||||
These are independent format examples; the synthetic provider does not satisfy
|
||||
the earlier examples' OpenRouter reference. An assembled configuration must
|
||||
supply its selected references through ordinary configuration and existing
|
||||
PromptKit validation/selection rules.
|
||||
|
||||
Retain the existing `default_profile` field instead of also renaming it to
|
||||
`profile`. Reducing nesting and making identity explicit are the changes under
|
||||
evaluation; unrelated field renames are unnecessary.
|
||||
|
||||
### Identity And Public References
|
||||
|
||||
Register these record identities with ConfigKit:
|
||||
|
||||
| Configuration path | Identity fields, in order |
|
||||
| --- | --- |
|
||||
| `backends` | `namespace`, `id` |
|
||||
| `profiles` | `namespace`, `id` |
|
||||
| `prompts` | `namespace`, `id`, `version` |
|
||||
|
||||
PromptKit turns each final `(namespace, id)` pair into its public
|
||||
`namespace/id` identifier after handoff; the prompt version remains a separate
|
||||
selection dimension. The conversion creates runtime indexes, not another merge
|
||||
or source-processing pass. It must reject invalid final domain identities rather
|
||||
than silently re-keying them.
|
||||
|
||||
Require identity fields to be explicitly present strings in every record,
|
||||
including partial override records. A prompt's nested `version` is a prompt
|
||||
identity component, not the protected top-level specification declaration.
|
||||
Do not derive any identity component from a typed default, parent, filename,
|
||||
collection metadata entry, or caller execution scope: matching happens before
|
||||
those application-level interpretations.
|
||||
|
||||
For unqualified application definitions, use `namespace: ""` explicitly; their
|
||||
public identifier is the local `id` alone, without a leading slash.
|
||||
Nonempty namespaces and local IDs follow the accepted namespace grammar;
|
||||
local IDs cannot contain `/`. Preserve exact spelling. PromptKit owns these
|
||||
domain checks on the final values; ConfigKit only requires usable structural
|
||||
identity fields and compares exact string tuples. Distinct tuples must never
|
||||
be conflated by concatenating fields with an unescaped delimiter internally.
|
||||
|
||||
Stored `default_profile` and `backend` references remain fully qualified or
|
||||
exact unqualified strings, as already selected in the namespace roadmap.
|
||||
Provider model values retain their existing syntax, including slashes.
|
||||
|
||||
## Proposed ConfigKit Contract
|
||||
|
||||
### Explicit Registration
|
||||
|
||||
The application's ConfigKit definition declares record-sequence rules at exact
|
||||
semantic paths, with ordered identity field names. The table above is a
|
||||
conceptual registration, not a proposed Go API declaration. ConfigKit does not
|
||||
guess from field names such as `id`, and configuration files cannot silently
|
||||
switch their own merge policy. No arbitrary merge callbacks are required.
|
||||
|
||||
An initial implementation only needs direct string identity fields at explicitly
|
||||
registered paths. Wildcard registration, computed keys, key normalization,
|
||||
implicit identity defaults, and nested identity expressions are not required
|
||||
by this proposal.
|
||||
|
||||
At a registered path, a non-null contribution must be a sequence of mappings.
|
||||
Every record must supply all structural identity fields with the declared
|
||||
string type. Missing/null/non-string identity fields or non-mapping records
|
||||
are ConfigKit structural errors: the loader cannot assign them a record identity.
|
||||
These errors cannot be hidden by a later layer. Nonidentity body fields retain
|
||||
the existing final-value decoding/validation lifecycle.
|
||||
|
||||
For consistency with duplicate mapping-key handling, recommend rejecting two
|
||||
records with the same tuple within a single source sequence. Across separate
|
||||
sources, matching tuples participate in normal composition as described below.
|
||||
This is a proposed explicit upstream rule, not a claim about current ConfigKit
|
||||
or a PromptKit source-level duplicate scan.
|
||||
|
||||
### Strict Composition And Overlay
|
||||
|
||||
Treat identity fields as the record's structural key. Their repeated equal
|
||||
values are not overlapping body fields that cause composition conflicts.
|
||||
Retain the fields in the final record and preserve their origin information.
|
||||
All remaining fields form the body to which existing mapping rules apply.
|
||||
|
||||
| Contributions at a registered path | Proposed result |
|
||||
| --- | --- |
|
||||
| Different identity tuples in one group or different layers | Retain both records |
|
||||
| Same tuple across peer sources, disjoint body fields | Recursively compose one body |
|
||||
| Same tuple across peer sources, overlapping non-mapping body values | Composition conflict, even if equal |
|
||||
| Same tuple in a higher-priority layer | Recursively overlay the higher body on the lower body |
|
||||
| Same prompt namespace/local ID but different prompt version | Distinct records |
|
||||
| Identity field changed in a later contribution | A different record; never an implicit rename of the old record |
|
||||
|
||||
Once a tuple is selected for matching, identity fields cannot themselves be
|
||||
overlaid into a different tuple. This avoids record identity changing during
|
||||
composition. A higher layer need only repeat the tuple and changed body fields:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
profiles:
|
||||
- namespace: provider
|
||||
id: brief
|
||||
temperature: 0.1
|
||||
```
|
||||
|
||||
The provider/backend/model fields inherited through layering remain. A new
|
||||
record introduced by an override still undergoes ordinary final validation;
|
||||
matching by identity does not guarantee it is a complete runnable profile.
|
||||
|
||||
For registered sequences, recommend that `[]` contributes no records and does
|
||||
not clear lower records, like an empty keyed mapping. This differs deliberately
|
||||
from ordinary sequence replacement. Explicit null at the whole registered path
|
||||
uses ordinary cross-layer replacement and can clear that whole collection when
|
||||
the application's final schema permits null. Within strict composition, null
|
||||
conflicts with another present value as usual. No per-record deletion marker,
|
||||
rename operation, or general patch language is added.
|
||||
|
||||
Process tiers in precedence-assembly order, lowest first, with deterministic
|
||||
source order within a tier. Preserve first-contribution order for distinct
|
||||
records, retain a matched record's position, and append newly encountered
|
||||
tuples. This makes output deterministic without giving position precedence or
|
||||
identity meaning; acquisition order need not equal assembly order. PromptKit
|
||||
can still sort its public inventory independently.
|
||||
|
||||
**Unregistered sequences keep all current semantics.** In particular, `messages`
|
||||
remains atomic: it conflicts across strict peer definitions and is replaced
|
||||
as a whole by a later override. Identified record support must not turn every
|
||||
sequence into a union or keyed merge.
|
||||
|
||||
### Inheritance Within A Registered Sequence
|
||||
|
||||
The extension must give identified records a sibling identity space. For
|
||||
composite identities, recommend a structural `extends` mapping containing the
|
||||
complete parent tuple. A profile example is:
|
||||
|
||||
```yaml
|
||||
profiles:
|
||||
- namespace: weatherreporter
|
||||
id: brief
|
||||
extends:
|
||||
namespace: provider
|
||||
id: brief
|
||||
temperature: 0.4
|
||||
```
|
||||
|
||||
ConfigKit resolves this relationship within the same registered `profiles`
|
||||
sequence after all composition and precedence. It overlays the child's body
|
||||
over the parent's resolved body, retains the child's identity fields, and
|
||||
consumes `extends` before typed decoding. Parent identity fields are never
|
||||
inherited into the child. References for a three-field identity, such as a
|
||||
prompt record, must include all three fields; no version guessing or namespace
|
||||
fallback is introduced. References cannot cross resource paths.
|
||||
|
||||
Preserve existing behavior for omitted relationships, `extends: null`, missing
|
||||
parents, cycles, and overridden relationships. A partial child contribution
|
||||
can retain a lower-layer relationship, and only final active relationships are
|
||||
resolved. Inherited file-backed content keeps the declaring field's source
|
||||
context, not the child's source directory.
|
||||
|
||||
This structural reference form is only enabled for records at registered paths.
|
||||
Existing mapping-sibling string inheritance remains unchanged elsewhere. A
|
||||
future single-field record rule could use that same field in the reference
|
||||
mapping; no PromptKit-specific interpretation of slash-separated parent strings
|
||||
is needed inside ConfigKit.
|
||||
|
||||
### Provenance, Inspection, And Typed Handoff
|
||||
|
||||
ConfigKit owns record matching and provenance throughout assembly. A conflict
|
||||
must identify the record and conflicting source locations, not merely report
|
||||
that two sequences occupy `prompts`. Preserve ConfigKit's safe diagnostic
|
||||
contract when representing that identity; do not indiscriminately echo input
|
||||
field values in error messages. Identity-field declarations retain their
|
||||
contributing locations even when those equal structural fields do not conflict.
|
||||
|
||||
Keep the final application-facing shape as a sequence of records, suitable for
|
||||
ordinary slice decoding and effective-config rendering. ConfigKit can use a
|
||||
private identity index, but should not expose private normalized nodes to
|
||||
PromptKit. Final body presence/null state, field origins, inheritance history,
|
||||
redaction, and passive source resource contexts must survive matching.
|
||||
|
||||
No new public identity-selector path language is required for this proposal.
|
||||
Inspection may address final records by sequence index, with ConfigKit mapping
|
||||
effective field paths to the appropriate historical source locations internally.
|
||||
Indexes are snapshot-specific; consumers locate a record by its identity before
|
||||
constructing an indexed path. Histories must not become attached to another
|
||||
record merely because its source position differed. Existing positional diff
|
||||
behavior need not become an identity-aware cross-snapshot diff in this work.
|
||||
|
||||
Rules must apply consistently to all enabled source kinds and composition
|
||||
entry points, including imports and layered input. Existing explicit CLI
|
||||
overrides must not leave duplicate or malformed structural identities in the
|
||||
final registered sequences; ConfigKit owns their integration and consistency
|
||||
checks. Ordinary application resolution must not trigger another merge or
|
||||
inheritance pass. Detailed public option declarations and implementation
|
||||
mechanics belong in the upstream design if this proposal is selected.
|
||||
|
||||
## Collection Metadata, Versions, And Assembly
|
||||
|
||||
Retain proposal 1's ordinary `collections.<namespace>.version` metadata and
|
||||
effective-descriptor inventory. It is distinct from the generic ConfigKit term
|
||||
"record sequence." Collection declarations still follow mapping composition;
|
||||
they are not a source registry or exclusive ownership claim. Repeated metadata
|
||||
release strings conflict in a strict peer group and can be overridden in a
|
||||
later layer. PromptKit does not add an independent duplicate-namespace scan.
|
||||
|
||||
Also retain proposal 1's main-owned `version: 1` declaration and its proposed
|
||||
explicit-version requirement. The value denotes the specification for the
|
||||
assembled configuration, not each imported package. Prompt record versions and
|
||||
collection release strings do not change that ownership rule. These proposals
|
||||
are alternative candidates for a future standard; they are not two simultaneously
|
||||
supported meanings for a released specification version.
|
||||
|
||||
Combine peer collection inputs in one strict underlay group; use later groups
|
||||
or main for intentional overrides. Callers continue to choose grouping and
|
||||
precedence. Directory inputs and explicit imports use existing ConfigKit
|
||||
selection and resource-context rules. There is no PromptKit pre-parser that
|
||||
reformats records, removes version fields, or replays the original sources.
|
||||
|
||||
**Independent collection specification checks remain unresolved.** This bounded
|
||||
extension does not permit imported or underlay roots to declare their own
|
||||
protected top-level `version`. A publisher must still supply configuration
|
||||
compatible with the selected main standard. Proposal 3 may consider a broader
|
||||
source/version contract; proposal 2 must not imply that record identity solves
|
||||
that separate issue.
|
||||
|
||||
## Ergonomic Alternatives And Tradeoffs
|
||||
|
||||
The first syntax discussed is also compatible with the generic extension:
|
||||
|
||||
```yaml
|
||||
prompts:
|
||||
- id: weatherreporter/summarize.alerts
|
||||
version: "1"
|
||||
default_profile: openrouter/gemini-flash-latest
|
||||
messages:
|
||||
- role: user
|
||||
content: Summarize the weather alerts.
|
||||
output:
|
||||
format: text
|
||||
validation_mode: none
|
||||
```
|
||||
|
||||
That alternative registers prompt identity as `(id, version)` and profile/backend
|
||||
identity as `(id)`. It is simpler to align with public reference strings and
|
||||
requires fewer identity fields in partial overrides. It repeats the namespace
|
||||
inside each full ID and gives authors no separate namespace field.
|
||||
|
||||
Prefer the composite form for explicit author-facing fields and easier editing
|
||||
of local names. Do not support both forms opportunistically in the same standard:
|
||||
that would require aliasing or normalization before identity matching. Select
|
||||
one representation for the adopted specification. The first form remains a
|
||||
reasonable alternative if the extra namespace line proves more cumbersome than
|
||||
the qualified string.
|
||||
|
||||
Retaining keyed mappings only for profiles could avoid extending inheritance
|
||||
to records, but would give authors different identity conventions by resource
|
||||
type. The recommendation favors a consistent record model and includes the
|
||||
necessary generic inheritance work explicitly.
|
||||
|
||||
| Concern | Proposal 1 | Proposal 2 |
|
||||
| --- | --- | --- |
|
||||
| Author identity | Qualified YAML mapping key | Explicit namespace/local-ID fields |
|
||||
| Prompt version | Nested mapping key | Field in each prompt record |
|
||||
| Cross-source composition | Current ConfigKit | Opt-in record identity extension |
|
||||
| Body conflicts and precedence | Mapping rules | Same mapping rules after tuple matching |
|
||||
| Root `prompts:` wrapper | Required | Required |
|
||||
| Provider model strings and execution references | Unchanged | Unchanged |
|
||||
| Independent imported specification checks | Unavailable | Still unavailable |
|
||||
| Main maintenance cost | PromptKit schema/API work | PromptKit work plus ConfigKit record lifecycle support |
|
||||
|
||||
This is more than a syntax-only change, but remains bounded: it introduces one
|
||||
generic representation for identified entries while preserving configuration
|
||||
source ownership and ordinary merge policy. It does not introduce collection
|
||||
installation, dependency resolution, namespace ownership, mounted sources,
|
||||
arbitrary transforms, or a general-purpose merge strategy system.
|
||||
|
||||
## Delivery And Validation
|
||||
|
||||
If selected, agree the upstream ConfigKit record contract first, implement and
|
||||
test it there, then adopt that capability in PromptKit's prospective schema.
|
||||
PromptKit would decode final records, validate domain identities/settings, build
|
||||
its ordinary execution indexes, and implement the already accepted scope and
|
||||
resource-discovery behavior plus the proposed collection inventory. Bundled
|
||||
catalog/profile removal remains the accepted direction.
|
||||
|
||||
Migration must convert each old keyed resource into its chosen record identity,
|
||||
flatten prompt-version entries, update any inheritance reference syntax, and
|
||||
preserve provider model strings. Choose specification and software release
|
||||
versions deliberately; do not silently reinterpret deployed configuration.
|
||||
|
||||
The upstream acceptance cases should include:
|
||||
|
||||
- Different tuples coexist; same local prompt names in different namespaces
|
||||
never collide; different versions of one prompt remain separate.
|
||||
- Matching tuples compose disjoint bodies but reject overlapping scalar/null/
|
||||
ordinary-sequence body fields, including equal values.
|
||||
- Matching tuples overlay across tiers without deleting unrelated records.
|
||||
Changing a tuple adds another record; `[]`, whole-path null, and ordinary
|
||||
message sequences follow their distinct documented semantics.
|
||||
- Missing or malformed identity fields and repeated tuples in one source fail
|
||||
structurally; identity comparisons cannot collide through delimiter encoding.
|
||||
- Composite inheritance resolves final relationships, preserves child identity,
|
||||
rejects missing/cyclic parents, and retains declaring resource contexts.
|
||||
- Matching, effective indexes, source positions, sensitivity, and provenance
|
||||
remain consistent through imports, overrides, inheritance, and rendering.
|
||||
- Unregistered configuration loads and ordinary sequence behavior are unchanged.
|
||||
- Existing version-path protections remain intact; record `version` fields are
|
||||
not mistaken for the protected root field.
|
||||
|
||||
PromptKit acceptance should exercise the authoring examples, final identity
|
||||
conversion, scoped selection, metadata inventory, and migrated references with
|
||||
offline collaborators. The record composition and inheritance examples require
|
||||
the proposed upstream extension; they are not executable supported workflows
|
||||
on ConfigKit v0.7.1 today. Syntax checks and current-behavior probes can establish
|
||||
the starting point, but cannot validate an unimplemented extension.
|
||||
|
||||
Review verification on 2026-10-14: a temporary offline consumer of the local
|
||||
ConfigKit checkout decoded the five examples without the new inheritance form,
|
||||
confirmed that the composite `extends` example is rejected today, and confirmed
|
||||
current sequence conflict/replacement behavior across peer and precedence layers.
|
||||
Local documentation links and whitespace checks passed. The temporary consumer
|
||||
and its module replacement are outside both repositories.
|
||||
|
||||
This proposal remains for evaluation alongside proposal 1. The parent roadmap's
|
||||
configuration decision remains open. Proposal 3 develops the alternative based
|
||||
on source placement; independent collection specification checking remains open.
|
||||
@@ -1,15 +1,15 @@
|
||||
# Proposal 3: Collections With Mounted Configuration Fragments
|
||||
|
||||
Status: proposed PromptKit standard; not implemented in PromptKit. Required
|
||||
Status: selected configuration direction; not implemented in PromptKit. Required
|
||||
ConfigKit capabilities are implemented on its development branch, reviewed at
|
||||
`e66c371` on 2026-10-16, but are not in PromptKit's selected v0.7.1 dependency.
|
||||
The recommended direction uses collection-local mapping keys, one installed
|
||||
definition per prompt, and an optional flat prompt `version` field. The latest
|
||||
review agrees on shared source checks using `IfPresent` and a distinct collection
|
||||
`release_version` field; remaining PromptKit decisions are listed below. Compare
|
||||
[proposal 1](configuration-collections-current-configkit.md) and
|
||||
[proposal 2](configuration-collections-identified-records.md); the parent
|
||||
[namespace roadmap](namespaces.md) owns the shared decisions.
|
||||
`release_version` field; remaining PromptKit decisions are listed below. The
|
||||
parent [namespace roadmap](namespaces.md) owns the shared decisions. Unselected
|
||||
proposals 1 and 2 have been retired; their history and the separately captured
|
||||
upstream request are recorded below.
|
||||
|
||||
## Recommendation
|
||||
|
||||
@@ -25,8 +25,8 @@ keys after ConfigKit hands off the resolved configuration.
|
||||
|
||||
There is one installed definition per qualified prompt ID. Its optional
|
||||
`version` field describes that definition; it does not create another identity
|
||||
or select a merge strategy. This removes the need for proposal 2's identified
|
||||
record sequences and for the current nested prompt-version mapping.
|
||||
or select a merge strategy. This avoids identified record sequences and the
|
||||
current nested prompt-version mapping.
|
||||
|
||||
Placement belongs to ConfigKit. PromptKit must not parse, wrap, or rewrite each
|
||||
source itself, nor impose duplicate-namespace checks before composition. This
|
||||
@@ -241,8 +241,8 @@ To retain unqualified application resources, recommend optional root-level
|
||||
using the same definition shapes. They produce unqualified public IDs. Under
|
||||
this proposal, namespaced definitions belong under `collections`, not a second
|
||||
qualified-key spelling in those root maps. This avoids two configuration paths
|
||||
producing the same public identity. This representation is a recommendation
|
||||
for proposal 3, not a change to today's accepted format.
|
||||
producing the same public identity. This representation belongs to the selected
|
||||
future direction; it does not change today's implemented format.
|
||||
|
||||
Stored references such as `default_profile`, profile `backend`, and smoke-test
|
||||
profile defaults remain exact public references. Nesting does not automatically
|
||||
@@ -272,10 +272,9 @@ is a simpler alternative but requires more consumer changes; settle the public
|
||||
API shape before implementation. Listings should identify one prompt per ID
|
||||
and expose the optional declared version separately from identity.
|
||||
|
||||
This intentionally supersedes multi-version preservation for this alternative.
|
||||
Proposals 1 and 2 retain their earlier assumptions for comparison. The parent
|
||||
roadmap's version-selection and listing language needs corresponding revision
|
||||
if proposal 3 is adopted.
|
||||
This deliberately replaces the earlier multi-version preservation assumption.
|
||||
The selected direction identifies prompts by ID and exposes an optional version
|
||||
label; the request-version and listing API details remain open below.
|
||||
|
||||
## ConfigKit Composition Boundary
|
||||
|
||||
@@ -346,8 +345,8 @@ unsupported declarations through the ConfigKit checker. The handling of an
|
||||
absent main declaration remains an explicit decision below. Accept additional
|
||||
versions only when PromptKit actually supports their format semantics: accepting
|
||||
a header does not migrate its payload or independently validate a fragment's
|
||||
complete schema. The three proposals are alternative candidate formats, not
|
||||
interchangeable released meanings of specification version 1.
|
||||
complete schema. The retired proposals were alternatives, not released formats
|
||||
sharing specification version 1.
|
||||
|
||||
The selected initial direction is `SourceVersionModeIfPresent`:
|
||||
|
||||
@@ -424,25 +423,33 @@ historical source ownership, or proof of unchanged published contents. Operator
|
||||
overrides may change resources while retaining a release label. Engine
|
||||
construction captures definitions; edits require a replacement engine.
|
||||
|
||||
## Comparison And Migration
|
||||
## Retired Alternatives And Upstream Request
|
||||
|
||||
| Concern | Proposal 1 | Proposal 2 | Proposal 3 |
|
||||
| --- | --- | --- | --- |
|
||||
| Author identity | Qualified mapping key | Namespace/local-ID fields | Local mapping key beneath a mounted collection |
|
||||
| Prompt version | Required nested key | Required identity field | Optional descriptive field |
|
||||
| Multiple installed versions per prompt | Supported | Supported | Not supported |
|
||||
| Repeated resource wrapper in fragments | Required | Required | Omitted through placement |
|
||||
| Composition machinery | Existing mappings | Identified record sequences | Existing mappings after placement |
|
||||
| Upstream prerequisite | None beyond its original baseline | Proposed record composition and inheritance | Placement, relative imports, and shared source checks implemented in development |
|
||||
| Cross-collection inheritance | Existing qualified sibling keys | Proposed tuple references | Requires a separate extension or authored flattening |
|
||||
| Source specification checks as described | Main only | Main only | Shared policy; non-main declarations checked when present |
|
||||
The unselected proposals were retired after the identified-record design was
|
||||
captured for separate upstream consideration. Both original documents remain
|
||||
available in PromptKit Git history at `b5866dd`:
|
||||
|
||||
Proposals 1 and 2 retain their original assumptions for historical comparison.
|
||||
Proposal 3 is the recommended direction for the stated one-installed-prompt
|
||||
requirement. Its authoring economy follows from the configuration hierarchy,
|
||||
and it retains ordinary map composition. The tradeoffs are explicit assembly
|
||||
destinations, changed inheritance scope, and a deliberate reduction of prompt
|
||||
version selection to one installed definition.
|
||||
```sh
|
||||
git show b5866dd:docs/roadmap/configuration-collections-current-configkit.md
|
||||
git show b5866dd:docs/roadmap/configuration-collections-identified-records.md
|
||||
```
|
||||
|
||||
Proposal 1 used fully qualified mapping keys and the then-current ConfigKit
|
||||
composition behavior. Proposal 2 used explicit identity fields in record
|
||||
sequences and requested identity-based composition and inheritance. Neither is
|
||||
an active PromptKit implementation option. The selected mounted-mapping design
|
||||
meets the one-installed-prompt requirement with compact local keys and ordinary
|
||||
mapping composition.
|
||||
|
||||
Proposal 2's generic extension is preserved in the ConfigKit repository as
|
||||
`docs/roadmap/promptkit-identified-records-feature-request.md`. It requests
|
||||
explicit record-identity registration, composition and overlay by identity,
|
||||
record inheritance, deterministic ordering, and coherent inspection. That
|
||||
request is for upstream evaluation, not an accepted ConfigKit capability or a
|
||||
prerequisite of this roadmap. Retirement does not resolve the six remaining
|
||||
PromptKit decisions below.
|
||||
|
||||
## Migration
|
||||
|
||||
Migration must choose one installed definition for each former multi-version
|
||||
prompt, move any retained version into its optional field, and relocate
|
||||
@@ -524,7 +531,6 @@ remain before the PromptKit contract is complete:
|
||||
and migration examples. Direct mounted fragments remain a useful alternative
|
||||
for applications that already assemble sources themselves.
|
||||
|
||||
The parent roadmap still owns the overall configuration decision. Its older
|
||||
version-selection and metadata examples describe earlier alternatives; adopting
|
||||
this standard requires reconciling those details and updating current contracts
|
||||
when implementation lands.
|
||||
The parent roadmap records this selected direction. Resolve the remaining
|
||||
PromptKit choices here and update current contracts when implementation lands;
|
||||
retiring the alternatives does not authorize feature implementation.
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
Status: feature roadmap; not implemented. The reserved-slash naming convention,
|
||||
reference-resolution rules, decisions 1–3 (scope shape, validation, and integrated
|
||||
discovery filtering), and decision 4's move to application/operator-supplied
|
||||
configuration are accepted target behavior. Collection metadata, inventory, and
|
||||
specification-version integration remain pending in decision 5, subject to the
|
||||
ConfigKit boundary. Exact Go names and option types remain delivery details.
|
||||
configuration are accepted target behavior. Decision 5 selects mounted collections
|
||||
and shared source-version checking; its remaining policy and API choices are
|
||||
tracked in the collection roadmap, subject to the ConfigKit boundary. Exact Go
|
||||
names and option types remain delivery details.
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -82,8 +83,9 @@ A profile ID identifies execution settings. Its configured model value is
|
||||
still the identifier passed to the provider; qualifying the profile ID does
|
||||
not modify that value. Both example profiles may retain the configured model
|
||||
`google/gemma-4-31b-it`. Different profiles may select the same model with
|
||||
different settings. Prompt versions also remain separate from namespaces and
|
||||
continue to use the existing selection rules.
|
||||
different settings. Prompt version labels remain separate from namespaces. The
|
||||
selected collection format installs one definition per prompt ID; optional
|
||||
request-version handling remains a decision in the collection roadmap.
|
||||
|
||||
Retain unqualified and dotted IDs. Existing slash-containing IDs need review:
|
||||
those with one slash and nonempty components become qualified identities, while
|
||||
@@ -135,8 +137,8 @@ The accepted resolution rules, independent of the final scope API, are:
|
||||
|
||||
Keep qualification consistent across execution, preparation, request validation,
|
||||
prompt/profile inspection, and applicable smoke-test selections. Namespace
|
||||
selection must not change request override precedence, prompt version selection,
|
||||
or provider model strings.
|
||||
selection must not change request override precedence, the chosen request-version
|
||||
semantics, or provider model strings.
|
||||
|
||||
### Local And Qualified References In One Operation
|
||||
|
||||
@@ -288,11 +290,11 @@ follow the eventual decision 5:
|
||||
and all-namespaces filters override that default for the current listing only.
|
||||
- A valid namespace with no matches produces an empty listing. Namespace
|
||||
filtering respects resource type and exact namespace boundaries.
|
||||
- Existing exact-ID calls using valid IDs, intentional overlays, and prompt
|
||||
versions retain their behavior. Migrated catalog references resolve to their
|
||||
intended resources without collisions.
|
||||
- Listings preserve full IDs and separate prompt versions. Qualified results
|
||||
round-trip through either engine or view; unqualified results round-trip
|
||||
- Exact-ID calls using valid IDs and intentional overlays retain their behavior.
|
||||
Migrated catalog references resolve without collisions; the collection roadmap
|
||||
owns migration to one installed prompt and optional version labels.
|
||||
- Listings preserve full IDs and separate optional prompt version labels.
|
||||
Qualified results round-trip through either engine or view; unqualified results round-trip
|
||||
through the engine without a corresponding scope.
|
||||
- Representative validation, inspection, execution, and smoke-test paths use
|
||||
the same qualification rules without duplicating every test at every layer.
|
||||
@@ -410,9 +412,10 @@ with no matching resources returns an empty listing. Represent default, named,
|
||||
unqualified-only, and all-namespaces selections distinctly in the API; do not
|
||||
overload an empty string to mean several of them.
|
||||
|
||||
Return full IDs, retaining prompt versions as separate identity fields. Do not
|
||||
invent a named namespace such as `default` for unqualified resources. Namespace
|
||||
enumeration excludes that unnamed group. Use deterministic ordering consistent
|
||||
Return full IDs with optional prompt version labels separately; the full ID
|
||||
identifies the installed prompt. Do not invent a named namespace such as `default`
|
||||
for unqualified resources. Namespace enumeration excludes that unnamed group.
|
||||
Use deterministic ordering consistent
|
||||
with existing listing contracts.
|
||||
|
||||
Qualified result IDs can be passed unchanged to either scoped or unscoped
|
||||
@@ -485,89 +488,35 @@ dependencies instead.
|
||||
|
||||
### 5. Collection Metadata And Specification Versioning (Open)
|
||||
|
||||
[Proposal 1: current ConfigKit](configuration-collections-current-configkit.md)
|
||||
develops a concrete configuration standard for the existing composition rules.
|
||||
[Proposal 2: identified records](configuration-collections-identified-records.md)
|
||||
uses an opt-in upstream extension for identity-based record composition and
|
||||
inheritance. [Proposal 3: mounted fragments](configuration-collections-mounted-fragments.md)
|
||||
uses explicit upstream source placement and collection-local mapping keys,
|
||||
with one installed definition per prompt and an optional flat version field.
|
||||
Proposal 3 now targets implemented ConfigKit development-branch capabilities,
|
||||
including relative imports and shared source-version checks with `IfPresent`. It
|
||||
uses `release_version` for collection metadata; proposals 1 and 2 preserve their
|
||||
earlier baselines for comparison. This overall decision remains open. Proposal 3
|
||||
deliberately revises the version-selection, metadata, and listing assumptions
|
||||
elsewhere in this roadmap if that alternative is adopted. Its remaining questions
|
||||
are PromptKit policy/API choices, not pending requests for those ConfigKit features.
|
||||
**Selected direction: [mounted collections](configuration-collections-mounted-fragments.md).**
|
||||
Proposal 3 is the active configuration roadmap. It uses collection-local mapping
|
||||
keys, one installed definition per prompt, and an optional flat prompt version.
|
||||
Input destinations, relative imports, and shared source-version checks are
|
||||
implemented in ConfigKit's reviewed development branch. PromptKit still needs
|
||||
to adopt a suitable dependency release and implement its new schema.
|
||||
|
||||
**Desired capability:** describe collection namespace and release version in
|
||||
configuration and expose an API through which downstream applications can list
|
||||
effective collection declarations captured by an engine. A collection release
|
||||
version is distinct from an individual prompt version and from the PromptKit
|
||||
software version. Use top-level `version: 1` for PromptKit specification version
|
||||
1, following ConfigKit's version mechanism, rather than introducing a
|
||||
`promptkit_spec` field. The ownership and placement of that version declaration
|
||||
across multiple sources remain part of this open decision.
|
||||
Use shared specification checking with `IfPresent` and distinct collection
|
||||
`release_version` metadata. Collection entries can describe their layout through
|
||||
relative imports; applications select their sources and namespaces. PromptKit
|
||||
interprets the final collection/resource keys as qualified IDs after ConfigKit's
|
||||
handoff. It adds no manifest pre-parser, source-level namespace ownership rule,
|
||||
or history-based validation pass. Stored references remain exact public IDs.
|
||||
|
||||
The initially discussed root manifest contained `collection.namespace` and
|
||||
`collection.version`. That shape and a standard manifest filename are not
|
||||
settled. In particular, the proposal to load/check each manifest separately in
|
||||
PromptKit before composing definitions is withdrawn. PromptKit must respect the
|
||||
ConfigKit boundary described above, including for version checks and duplicate
|
||||
declarations.
|
||||
Proposals 1 and 2 were not selected and have been retired. Their original
|
||||
contents and the separately preserved ConfigKit identified-record request are
|
||||
recorded in the collection roadmap's
|
||||
[retirement note](configuration-collections-mounted-fragments.md#retired-alternatives-and-upstream-request).
|
||||
The record-sequence request is independent future upstream work and does not
|
||||
block the selected mapping design.
|
||||
|
||||
ConfigKit v0.7.1's layered-loading contract checks the configured application
|
||||
version path on the main input only. Underlay roots cannot claim that path,
|
||||
and imported fragments cannot independently declare it. ConfigKit supplies the
|
||||
version mechanism while the application defines supported specification values;
|
||||
this does not give PromptKit permission to implement an independent collection
|
||||
assembly or compatibility-checking pass.
|
||||
The collection roadmap owns the candidate schema, examples, version policies,
|
||||
metadata inventory, and migration requirements. Inventory describes effective
|
||||
collection declarations captured by the engine, not historical manifests or
|
||||
proof of unchanged published releases. Source explanation remains ConfigKit's
|
||||
inspection concern.
|
||||
|
||||
**Recommended starting point, pending decision: ordinary ConfigKit composition
|
||||
with collection metadata in final effective values.** For example, the main
|
||||
configuration could own `version: 1`, with a namespace-keyed collection mapping:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
collections:
|
||||
openrouter:
|
||||
version: "2026.10.13"
|
||||
weatherreporter:
|
||||
version: "2.4.0"
|
||||
```
|
||||
|
||||
This is a candidate shape, not an implemented or accepted schema. Other sources
|
||||
could contribute to `collections` without claiming the main version field.
|
||||
ConfigKit would decide whether contributions conflict or combine; PromptKit
|
||||
would interpret and validate only the final metadata. A namespace key would
|
||||
identify one effective entry without requiring a source-level uniqueness rule.
|
||||
It would not automatically qualify definition keys or stored references.
|
||||
|
||||
This approach reuses the existing composition contract and avoids a parallel
|
||||
manifest loader. Its limitation is that it does not independently check a
|
||||
specification declaration for each imported collection. An effective declared
|
||||
release version also does not prove that every resource still matches that
|
||||
release after operator overrides.
|
||||
|
||||
**Alternative: add collection/import compatibility support within ConfigKit
|
||||
before adopting independently versioned collection roots.** If every collection
|
||||
must declare its own specification version, design that capability in ConfigKit,
|
||||
including how versions and metadata interact with imports and layers. PromptKit
|
||||
would consume its resulting handoff and diagnostics. This could provide useful
|
||||
per-collection compatibility checks without violating ownership, but it expands
|
||||
the work into ConfigKit and requires a supported contract there before PromptKit
|
||||
can depend on it. No ConfigKit change is selected by this roadmap yet.
|
||||
|
||||
Under either approach, the inventory should describe effective collection
|
||||
metadata captured at engine construction, not reconstruct a historical list of
|
||||
loaded manifests. Source contributions and explanations remain ConfigKit
|
||||
inspection concerns. Inventory should not reread installed files or claim that
|
||||
declared versions prove unmodified published contents. Namespace enumeration
|
||||
from resource IDs remains independent of this metadata API.
|
||||
|
||||
**Pending question:** is ordinary composed collection metadata with one main
|
||||
specification declaration sufficient, or are independently version-checked
|
||||
collection roots essential enough to warrant ConfigKit work? Settle that before
|
||||
finalizing metadata schema, root-file conventions, inventory API values, or
|
||||
collection compatibility rules. Removal of bundled catalogs and built-in
|
||||
profiles remains accepted in either case.
|
||||
**Still open:** the [six remaining PromptKit decisions](configuration-collections-mounted-fragments.md#remaining-promptkit-decisions)
|
||||
cover main declaration requirements, exposing stricter checking, resources named
|
||||
`version`, request-version assertions, cross-collection inheritance, and consumer
|
||||
APIs/packaging. Selecting proposal 3 and retiring its alternatives does not settle
|
||||
those choices. Removal of bundled catalogs and built-in profiles remains accepted.
|
||||
|
||||
Reference in New Issue
Block a user