Record PromptKit feature request decisions
This commit is contained in:
@@ -1,15 +1,23 @@
|
||||
# PromptKit Feature Request: Mounted Collections And Specification Headers
|
||||
|
||||
Status: input destinations are implemented on the ConfigKit development branch
|
||||
(reviewed at `315f464`). Independent collection specification headers and relative
|
||||
import destinations are requested additions; not yet accepted or implemented.
|
||||
Status:
|
||||
|
||||
- Input destinations are implemented on the ConfigKit development branch
|
||||
(placement baseline reviewed at `315f464`).
|
||||
- Relative import destinations have been accepted and implementation is in
|
||||
progress; the [roadmap](relative-import-destinations.md) owns delivery scope.
|
||||
- Source specification headers have been partially accepted in the shared
|
||||
application-version-policy form described below. This does not accept
|
||||
PromptKit's original independent collection-header semantics. Design and
|
||||
implementation of this addition remain separate from relative import work.
|
||||
|
||||
## Requested Capability
|
||||
|
||||
Extend the public loading API so independently maintained collections can declare
|
||||
and check their specification compatibility and describe relative import
|
||||
destinations. Preserve the implemented capability to select a destination mapping
|
||||
path for each configuration input. The input's application content contributes
|
||||
Extend configuration loading with relative import destinations and opt-in
|
||||
checks that contributing sources declare a version accepted by the consumer's
|
||||
single configuration specification policy. Preserve the implemented capability
|
||||
to select a destination mapping path for each configuration input. The input's
|
||||
application content contributes
|
||||
beneath that path while retaining ConfigKit's normal composition, precedence,
|
||||
inheritance, validation, diagnostics, and inspection behavior.
|
||||
|
||||
@@ -17,7 +25,9 @@ PromptKit needs this capability for its proposal 3, **Collections With Mounted
|
||||
Configuration Fragments**, recorded in PromptKit's
|
||||
`docs/roadmap/configuration-collections-mounted-fragments.md`. This request
|
||||
describes the public API needs and observable acceptance criteria. It does not
|
||||
prescribe ConfigKit's internal design or an implementation plan.
|
||||
prescribe ConfigKit's internal design or an implementation plan. The disposition
|
||||
and revised source-version scope below supersede conflicting parts of PromptKit's
|
||||
original proposal.
|
||||
|
||||
The original request targeted ConfigKit v0.7.1. The development branch now
|
||||
supplies `Input.Destination` and `SourceInfo.Destination`, as documented in the
|
||||
@@ -211,8 +221,11 @@ version: "2.4.0"
|
||||
Mounted at `[collections, weatherreporter]`, that field is an ordinary collection
|
||||
release label. It must not be rejected as an attempt to contribute the protected
|
||||
root specification field. The same applies to a prompt's nested optional
|
||||
version. Only the main-owned specification declaration uses the application's
|
||||
configured [VersionRule](../config.md#application-schema-versions).
|
||||
version. This describes the existing placement baseline, with no new source
|
||||
checks enabled. The partially accepted extension will reuse the application's
|
||||
[VersionRule](../config.md#application-schema-versions) for source declarations;
|
||||
header lookup and its interaction with ordinary version payload remain design
|
||||
questions, not a guarantee that every source-local `version` stays unchecked.
|
||||
|
||||
Conversely, placement must not permit an underlay or imported fragment to claim
|
||||
or replace the actual protected specification path or an ancestor that would
|
||||
@@ -221,9 +234,11 @@ application paths, rather than reserving the spelling `version` in every source.
|
||||
Protection must remain valid with imports, inheritance, overlays, and explicit
|
||||
CLI overrides.
|
||||
|
||||
Retain the main-owned specification check with its existing lifecycle. The new
|
||||
collection-header checks below are explicit, separate source compatibility
|
||||
checks; they do not authorize contributions to the main-owned version path.
|
||||
Retain existing behavior when the new source checks are not enabled. The
|
||||
accepted direction extends the same application version policy across source
|
||||
files, rather than assigning separate policies to collections. Its interaction
|
||||
with protected-path ownership and declaration retention must be designed
|
||||
explicitly; it does not implicitly authorize version-field contributions.
|
||||
PromptKit does not need main mounted away from the root or integer-to-string
|
||||
conversion for every nested ordinary `version` field.
|
||||
|
||||
@@ -266,87 +281,84 @@ and resource-access behavior. Destinations must participate in documented load
|
||||
limits without creating a way to bypass them; this request does not prescribe
|
||||
new limit values or their accounting machinery.
|
||||
|
||||
## Requested Addition: Independent Collection Specification Headers
|
||||
## Partially Accepted Addition: Shared Source Specification Checks
|
||||
|
||||
### Consumer Need And Public API
|
||||
### Accepted Scope
|
||||
|
||||
Allow an application to attach an opt-in source specification rule to a selected
|
||||
collection entry `Input`. PromptKit would configure the source-local header path
|
||||
as `version` and supply its supported-specification policy. ConfigKit owns
|
||||
checking the declaration and delivering structured diagnostics within the same
|
||||
`LoadLayered` operation. This must not require PromptKit to open, parse, or load
|
||||
collection manifests separately.
|
||||
A ConfigKit consumer defines one configuration specification, which may evolve
|
||||
through versions. `Definition.Version` identifies the declaration path and the
|
||||
consumer's checker determines which versions are acceptable. The accepted
|
||||
extension lets the consumer apply that same policy across the source files
|
||||
contributing to a configuration, rather than checking only the main declaration.
|
||||
It does not introduce independent collection or subtree specification policies.
|
||||
|
||||
Reuse the public version vocabulary where appropriate: the checker should be
|
||||
able to distinguish absent, null, string, and strict decimal-integer declarations
|
||||
and receive their text without imposing SemVer. For PromptKit specification 1,
|
||||
`version: 1` and `version: "1"` can express the same supported identifier.
|
||||
PromptKit decides which declarations it accepts, including whether a missing
|
||||
header is an error. Exact API names and how the source rule relates to the
|
||||
existing `VersionRule` type are ConfigKit design decisions.
|
||||
The consumer can opt in with increasing strictness:
|
||||
|
||||
This is a separate rule from `Definition.Version`, which continues to describe
|
||||
the main-owned application specification. It checks a source's declared format,
|
||||
not its complete domain schema. Domain validation still runs on final effective
|
||||
configuration, not once per collection or fragment.
|
||||
1. **Current behavior:** retain existing loading and version-checking behavior,
|
||||
including existing protected-path restrictions. No new source-header check.
|
||||
2. **Check declarations when present:** a source that declares a version must
|
||||
satisfy `Definition.Version`; omission is allowed.
|
||||
3. **Require declarations:** every participating source must declare a version
|
||||
that satisfies `Definition.Version`; omission is an error.
|
||||
|
||||
The minimum API must support several collection entry inputs in one load, each
|
||||
with a destination and an explicitly assigned source-header policy. Source
|
||||
selection determines which documents are entries. Neither a filename nor the
|
||||
mere presence of a field named `version` automatically enables header checking.
|
||||
No YAML-selected executable checker or general source-validation callback is
|
||||
requested.
|
||||
Acceptance is determined by the existing consumer-supplied checker, not by a
|
||||
new ConfigKit-owned expected string or automatic equality with the main file's
|
||||
declaration. A consumer may accept several compatible versions. A declaration
|
||||
rejected under the selected mode fails the attempted load through structured
|
||||
errors, with no usable partial result; a higher-precedence payload cannot turn
|
||||
an incompatible source declaration into an acceptable one.
|
||||
|
||||
### Header Scope And Payload
|
||||
This establishes that checked sources declare an accepted specification version.
|
||||
It does not prove that every fragment conforms to its declaration. Existing
|
||||
final decoding and application validation still determine the validity of the
|
||||
assembled configuration; fragments are not independently loaded as complete
|
||||
applications.
|
||||
|
||||
Recommend one required specification declaration per selected collection entry,
|
||||
with its ordinary imported fragments authored under that declared specification.
|
||||
Do not require a repeated header in every prompt/profile fragment. Importing a
|
||||
fragment does not give it an independent header rule; in particular, its ordinary
|
||||
release or prompt `version` must not be consumed as a specification header.
|
||||
### Difference From PromptKit's Original Proposal
|
||||
|
||||
For an explicitly configured entry, check its own declaration independently of
|
||||
other inputs and precedence layers. Another source cannot supply a missing
|
||||
header, and a higher-priority override cannot conceal an unsupported declaration.
|
||||
Any rejected entry fails the whole load with no usable partial result, even if
|
||||
its payload would subsequently be superseded. Reusing a physical source across
|
||||
allowed separate tiers retains existing source-reuse semantics; this request
|
||||
adds no source-uniqueness policy.
|
||||
PromptKit originally requested explicitly selected collection-entry rules,
|
||||
separate from `Definition.Version`, with ordinary imports exempt from independent
|
||||
checks. It also recommended consuming accepted entry headers and exposing them
|
||||
as source evidence while leaving imported release metadata untouched.
|
||||
|
||||
After an entry header is accepted, recommend consuming it as structural source
|
||||
metadata: it does not contribute at the mounted application path. For example,
|
||||
entry `version: 1` must not become `collections.weatherreporter.version`. The
|
||||
collection release label can be contributed separately as ordinary payload.
|
||||
This distinction also prevents unrelated collection specification declarations
|
||||
from conflicting during strict composition.
|
||||
That full set of semantics has not been accepted. The accepted direction uses
|
||||
one shared `Definition.Version` policy and optional or required declarations
|
||||
across participating sources. Separately versioned subsets or collections are
|
||||
outside this addition's scope and may be considered independently in the future.
|
||||
Header consumption and inspection from the original proposal remain design
|
||||
suggestions, not accepted requirements.
|
||||
|
||||
This consumption applies only to the explicitly selected source header. It
|
||||
must not remove nested versions, imported metadata, or the main application's
|
||||
existing version field. The API should make the distinction between a consumed
|
||||
source header and a retained main declaration explicit; it must not silently
|
||||
change existing `Definition.Version` behavior.
|
||||
### Remaining Design Work
|
||||
|
||||
### Diagnostics And Inspection
|
||||
The following details remain to be resolved before implementation:
|
||||
|
||||
Expose the checked declaration and its source-local location through supported
|
||||
source inspection, or equivalent public metadata. Consumers should be able to
|
||||
identify the source, header path, and accepted declaration without rereading
|
||||
files. Preserve the normal distinction between authored input evidence and
|
||||
rendered effective application configuration: a consumed header is evidence of
|
||||
source compatibility, not an effective domain field.
|
||||
- How the configured declaration path is interpreted for individual sources,
|
||||
particularly before destination placement.
|
||||
- Which source kinds and roles participate, including direct underlay inputs,
|
||||
transitive imports, and other contributions.
|
||||
- Whether checked declarations are consumed or retained, how that interacts
|
||||
with composition and main-owned version protection, and what inspection
|
||||
evidence is exposed.
|
||||
- How null and malformed declarations behave in each mode, preserving the
|
||||
distinction between absence and a present declaration and considering the
|
||||
existing string/decimal-integer version vocabulary.
|
||||
- The opt-in API, callback lifecycle, and source-local diagnostic attribution.
|
||||
|
||||
Header failures and warnings should use ConfigKit's structured diagnostics and
|
||||
normal disclosure rules. Report the actual entry source and header location,
|
||||
or a source-location fallback when the header is absent; do not attribute them to the
|
||||
unrelated protected root field or invent an effective payload field. The
|
||||
source's destination remains inspectable. Exact diagnostic codes and inspection
|
||||
types are left to ConfigKit.
|
||||
In particular, the original example of an imported `version: "2.4.0"` release
|
||||
label is not guaranteed to remain outside checking in an enabled mode. That
|
||||
depends on the chosen header lookup semantics. No automatic field consumption,
|
||||
new coercion, or per-collection checker should be inferred from partial acceptance.
|
||||
|
||||
## Requested Addition: Relative Import Destinations
|
||||
|
||||
Disposition: accepted; implementation is in progress under the
|
||||
[relative import destinations roadmap](relative-import-destinations.md).
|
||||
The behavior below records the accepted capability; exact syntax and completion
|
||||
status follow that work, rather than implying a released feature.
|
||||
|
||||
Extend the public YAML import directive so a `path` or `glob` import can specify
|
||||
a relative destination as literal mapping-key segments. An illustrative spelling
|
||||
is `destination: [prompts]`; the exact directive field name remains a proposal.
|
||||
a relative destination as literal mapping-key segments. The roadmap selects
|
||||
`destination` as a sequence of strings, for example `destination: [prompts]`.
|
||||
|
||||
The public behavior should be:
|
||||
|
||||
@@ -375,13 +387,13 @@ This is declarative access to the existing placement capability. It does not
|
||||
request recursive glob syntax, implicit directory scanning, namespace inference,
|
||||
or a new composition strategy.
|
||||
|
||||
## Combined Collection Entry Example
|
||||
## Relative Import Collection Entry Example
|
||||
|
||||
With both additions, an entry document selected by the application with a source
|
||||
header rule and destination `[collections, weatherreporter]` could contain:
|
||||
An entry document selected by the application with destination
|
||||
`[collections, weatherreporter]` could describe its layout as follows. This
|
||||
example illustrates relative imports only and assumes no new source checks:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
configkit:
|
||||
imports:
|
||||
- path: metadata.yml
|
||||
@@ -398,18 +410,16 @@ glob assumes matching files; collections can omit unused categories or use
|
||||
existing optional-import behavior. The application still selects and provisions
|
||||
the collection and assigns its namespace. ConfigKit does not discover it.
|
||||
|
||||
The entry's `version: 1` is checked and consumed. Its `metadata.yml` can contain
|
||||
`version: "2.4.0"`, retained as the collection's ordinary release label because
|
||||
that import has no independent header rule and inherits the collection
|
||||
destination. Prompt fragments retain local mapping keys and optional prompt
|
||||
versions, and are placed beneath the collection's `prompts` mapping. The main
|
||||
application can independently retain its own `version: 1` declaration.
|
||||
With current source-version behavior, `metadata.yml` can contain
|
||||
`version: "2.4.0"` as an ordinary mounted collection release label. Prompt
|
||||
fragments retain local mapping keys and optional prompt versions, and contribute
|
||||
beneath the collection's `prompts` mapping. The main application can retain its
|
||||
own version declaration. Enabling the proposed shared source checks may require
|
||||
changes to these files once declaration lookup and retention are defined.
|
||||
|
||||
Thus publishers can describe their collection layout, authors can keep compact
|
||||
fragments, and operators can compose several independently checked collections
|
||||
without application-side source rewriting. These checks establish declared
|
||||
specification compatibility, not package authenticity, release integrity, or
|
||||
proof that every fragment was authored correctly.
|
||||
Publishers can describe collection layout while applications select collections
|
||||
and destinations. The later shared-version feature will add opt-in declaration
|
||||
checking; it does not establish package authenticity or release integrity.
|
||||
|
||||
## Deferred And Excluded Work
|
||||
|
||||
@@ -432,7 +442,10 @@ inventory, and execution APIs remain PromptKit responsibilities.
|
||||
|
||||
## Public Acceptance Scenarios
|
||||
|
||||
Evaluate the extension through supported public loading and inspection APIs:
|
||||
Evaluate the implemented placement baseline and accepted relative-import
|
||||
extension through supported public loading and inspection APIs. Source-version
|
||||
rows below express the partially accepted direction; their unresolved details
|
||||
must be settled before they become implementation acceptance tests.
|
||||
|
||||
| Scenario | Expected consumer-visible result |
|
||||
| --- | --- |
|
||||
@@ -444,27 +457,33 @@ Evaluate the extension through supported public loading and inspection APIs:
|
||||
| Version-only prompt override | Label changes; omitted prompt body fields survive |
|
||||
| Nested mounted import without a destination directive | Imported fields contribute at the inherited destination |
|
||||
| Local profile inheritance across mounted peer fragments | Parent resolves at the effective sibling scope |
|
||||
| Collection metadata containing `version` mounted below root | Ordinary nested field, independent of root VersionRule |
|
||||
| Collection metadata containing `version` mounted below root, with new checks disabled | Existing ordinary nested-field behavior |
|
||||
| Mounted/imported contribution actually targeting the protected version path | Rejected under version ownership rules |
|
||||
| Mounted field using source-relative content, including inheritance | Original declaring resource context remains available |
|
||||
| Mounted explicit null and omitted field | Distinct effective presence information |
|
||||
| Mounted validation error or secret field | Effective paths, physical locations, and existing disclosure rules agree |
|
||||
| File, native filesystem, byte, reader, or mapping input with equivalent content | Equivalent application values, subject to existing source contracts |
|
||||
| Unsupported destination or failed load | Normal structured failure, no usable partial result |
|
||||
| Several collection entries with supported specification headers | Each declaration is independently accepted; payloads compose normally |
|
||||
| Missing, null, malformed, or unsupported entry header | ConfigKit reports structural/type errors or invokes the configured version policy as appropriate; rejection fails the whole load |
|
||||
| Unsupported entry superseded by a higher layer | Compatibility failure remains visible and fails loading |
|
||||
| Consumed entry header plus imported release metadata | Header is inspectable as source evidence; only the release label becomes the collection's ordinary version field |
|
||||
| Ordinary imported fragment containing `version` without a header rule | Field remains ordinary payload and is not independently consumed or checked |
|
||||
| Source-version checks disabled | Existing version-checking and protected-path behavior |
|
||||
| Check-when-present mode, declaration absent | Omission is allowed |
|
||||
| Check-when-present mode, declaration present | Must satisfy the shared `Definition.Version` policy |
|
||||
| Required mode, declaration absent | Structured load failure |
|
||||
| Required mode, declaration present | Must satisfy the shared `Definition.Version` policy |
|
||||
| Different declarations both accepted by the consumer checker | No additional exact-equality requirement |
|
||||
| Rejected source declaration with payload superseded by a higher layer | Rejection still fails the load |
|
||||
| Relative import destination omitted or empty | Existing inherited-destination behavior |
|
||||
| Entry at `[collections, weather]`, import at `[prompts]`, nested import at `[extras]` | Nested contribution appears beneath `[collections, weather, prompts, extras]` |
|
||||
| Glob import with a relative destination | Every matched contribution uses that destination and composes strictly |
|
||||
| Relative import destination with source-relative resource | Effective configuration path changes; resource base remains the declaring source |
|
||||
| Load without source-header rules or relative import directives | Existing loading and main VersionRule semantics remain unchanged |
|
||||
| Load without new source checks or relative import directives | Existing loading and main VersionRule semantics remain unchanged |
|
||||
|
||||
The requested outcome is a consumer that selects collection entry sources,
|
||||
destinations, and specification policies, performs one ordinary layered load,
|
||||
and receives final typed configuration with reliable diagnostics and inspection.
|
||||
Collection entries describe their own relative import placements, and unsupported
|
||||
source specifications fail independently of payload precedence. It should need no
|
||||
consumer-side source rewriting, generic merging, or provenance reconstruction.
|
||||
The relative-import outcome is a consumer that selects entry sources and
|
||||
destinations, performs one ordinary layered load, and receives final typed
|
||||
configuration with reliable diagnostics and inspection. Entry documents describe
|
||||
their own relative import placements without consumer-side source rewriting,
|
||||
generic merging, or provenance reconstruction.
|
||||
|
||||
The separately scoped, partially accepted source-version extension adds optional
|
||||
or required declaration checking through the consumer's single
|
||||
`Definition.Version` policy. It does not require or authorize independently
|
||||
versioned collections.
|
||||
|
||||
Reference in New Issue
Block a user