Align collection proposal with implemented ConfigKit capabilities
This commit is contained in:
@@ -1,18 +1,20 @@
|
||||
# Proposal 3: Collections With Mounted Configuration Fragments
|
||||
|
||||
Status: proposed alternative; not implemented. The authoring direction follows
|
||||
the discussion's preference for collection-local mapping keys, one installed
|
||||
definition per prompt, and an optional flat prompt `version` field. The overall
|
||||
configuration standard and upstream API still require selection. Compare
|
||||
Status: proposed PromptKit standard; 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.
|
||||
|
||||
## Recommendation
|
||||
|
||||
Ask ConfigKit to support an explicit destination path for configuration inputs.
|
||||
For example, inputs selected from a collection's `prompts` directory would
|
||||
contribute their document bodies beneath the literal configuration path
|
||||
Use ConfigKit's implemented input destinations and relative import destinations.
|
||||
For example, a collection entry can import its `prompts` directory beneath
|
||||
`[collections, weatherreporter, prompts]`. Authors write local prompt names and
|
||||
definitions without repeating either `prompts:` or the namespace in each file.
|
||||
|
||||
@@ -30,28 +32,36 @@ Placement belongs to ConfigKit. PromptKit must not parse, wrap, or rewrite each
|
||||
source itself, nor impose duplicate-namespace checks before composition. This
|
||||
preserves the accepted [configuration boundary](../adr/0001-configuration-boundary.md).
|
||||
|
||||
## Current Baseline And Required Extension
|
||||
## Reviewed Upstream Capabilities And Adoption Status
|
||||
|
||||
The reviewed ConfigKit checkout is v0.7.1, commit
|
||||
`6fffde4af8f31f99d3ee295c426eb3234cb0fb77`, also the dependency selected by
|
||||
PromptKit. Its [configuration contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.1/docs/config.md)
|
||||
and public `Input` declaration establish the relevant baseline:
|
||||
The reviewed ConfigKit development checkout is `e66c371`. Its public
|
||||
configuration contract (`docs/config.md`, sections “Input destinations” and
|
||||
“Shared source-version checks”) and ADRs 0011–0013 own the upstream behavior.
|
||||
PromptKit still selects ConfigKit v0.7.1; choose a released dependency containing
|
||||
these capabilities before implementation. This roadmap does not imply they are
|
||||
already available through PromptKit or select an upstream release number.
|
||||
|
||||
- Inputs select a source, import policy, and filesystem context. They do not
|
||||
expose a destination in the effective configuration tree.
|
||||
- YAML documents have mapping roots. Strict composition recursively combines
|
||||
mappings and rejects every overlapping non-mapping pair, even equal values.
|
||||
- Explicit precedence layers recursively overlay mappings; scalar, sequence,
|
||||
and null values replace lower values. File order does not confer precedence.
|
||||
- `extends` names an immediate mapping sibling and resolves after assembly.
|
||||
- The configured specification-version path is checked on main only and
|
||||
protected against contributions from fragments and lower layers.
|
||||
- Effective fields retain source origins and filesystem resource contexts.
|
||||
The implemented public surface provides:
|
||||
|
||||
The collection-shaped tree can be authored explicitly with current ConfigKit.
|
||||
Removing the repeated wrappers from source files requires the proposed mount
|
||||
capability. PromptKit also needs a new schema and runtime indexing changes;
|
||||
none of the proposed PromptKit examples are supported by its current schema.
|
||||
- `Input.Destination` for root-relative placement, and YAML import
|
||||
`destination: [prompts]` for placement relative to the immediate importing
|
||||
document. Glob matches share the declared destination; nested imports append
|
||||
to their immediate parent's destination.
|
||||
- `Options.SourceVersionMode` and `LayeredOptions.SourceVersionMode`, using one
|
||||
shared `Definition.Version` rule. Enabled modes interpret the rule's path in
|
||||
each document's source-local coordinates before placement and composition.
|
||||
- Consumption of accepted non-main specification headers, with the main header
|
||||
retained and protected at its effective application path.
|
||||
- `SourceInfo.Destination` and `SourceInfo.VersionCheck` for detached inspection
|
||||
evidence, alongside existing source locations and resource contexts.
|
||||
|
||||
Strict mapping composition, explicit precedence, atomic sequences, and local
|
||||
sibling inheritance retain their existing rules. ConfigKit owns the complete
|
||||
load; PromptKit interprets and validates final effective values. No further
|
||||
ConfigKit extension is required for the initial direction described here.
|
||||
|
||||
The new PromptKit schema and runtime indexes remain future work. The existing
|
||||
[format reference](../formats.md) remains authoritative until adoption.
|
||||
|
||||
## Authoring And Assembly
|
||||
|
||||
@@ -99,46 +109,68 @@ default:
|
||||
endpoint: https://inference.example.invalid/v1
|
||||
```
|
||||
|
||||
An optional `weatherreporter/collection.yml` contributes collection metadata:
|
||||
A conventional `weatherreporter/collection.yml` entry can declare the shared
|
||||
specification, optional collection release, and its layout:
|
||||
|
||||
```yaml
|
||||
version: "2.4.0"
|
||||
version: 1
|
||||
release_version: "2.4.0"
|
||||
configkit:
|
||||
imports:
|
||||
- glob: prompts/*.yml
|
||||
destination: [prompts]
|
||||
```
|
||||
|
||||
Here that field is a collection release label because the document is mounted
|
||||
at the collection node. It is not a PromptKit specification declaration. Keep
|
||||
these two uses explicit in author documentation and packaging examples.
|
||||
A provider entry can import `profiles/*.yml` at `[profiles]` and
|
||||
`backends/*.yml` at `[backends]` in the same way. Collection publishers choose
|
||||
which categories to include. A required glob must match; unused categories can
|
||||
be omitted or use ConfigKit's existing optional-import behavior. Ordinary
|
||||
fragments may omit specification headers under the selected `IfPresent` mode.
|
||||
An entry header is the recommended publishing convention, not a load-time
|
||||
requirement selectively enforced on entries by this mode.
|
||||
|
||||
The consuming application's source selection would express placements like
|
||||
these. Paths are illustrative; the destination column is a list of literal
|
||||
mapping keys, not a slash-delimited string or proposed API syntax.
|
||||
The application selects each entry, enables its imports, and supplies its
|
||||
namespace through the public input destination. For example, the following
|
||||
partial Go snippet uses implemented ConfigKit development-branch APIs:
|
||||
|
||||
| Selected source | Destination |
|
||||
```go
|
||||
entry := configkit.Input{
|
||||
Source: configkit.File("/usr/local/share/collections/weatherreporter/collection.yml"),
|
||||
Imports: true,
|
||||
Destination: configkit.Keys("collections", "weatherreporter"),
|
||||
}
|
||||
```
|
||||
|
||||
Put peer collection entries into one `Underlay` group's `Inputs`. Configure
|
||||
`LayeredOptions.SourceVersionMode` as `SourceVersionModeIfPresent` and
|
||||
`Definition.Version.Path` as `configkit.Keys("version")`, with PromptKit's
|
||||
supported-specification checker. The application main input remains at the
|
||||
root and declares `version: 1` in the examples below. Namespace selection and
|
||||
source selection require no manifest parsing in PromptKit.
|
||||
|
||||
| Selected source | Effective destination |
|
||||
| --- | --- |
|
||||
| Application main document | `[]` (configuration root) |
|
||||
| Application main document | Configuration root |
|
||||
| `weatherreporter/collection.yml` | `[collections, weatherreporter]` |
|
||||
| YAML fragments under `weatherreporter/prompts` | `[collections, weatherreporter, prompts]` |
|
||||
| YAML fragments under `homewatch/prompts` | `[collections, homewatch, prompts]` |
|
||||
| YAML fragments under `provider/profiles` | `[collections, provider, profiles]` |
|
||||
| YAML fragments under `provider/backends` | `[collections, provider, backends]` |
|
||||
| Its `prompts/*.yml` imports | `[collections, weatherreporter, prompts]` |
|
||||
| Homewatch entry and its prompt imports | `[collections, homewatch]` and `[collections, homewatch, prompts]` |
|
||||
| Provider entry and its profile/backend imports | `[collections, provider]`, then `[profiles]` or `[backends]` appended |
|
||||
|
||||
The namespace is supplied by the assembly declaration. A collection-selection
|
||||
helper could take it once and construct these destinations for conventional
|
||||
subdirectories without reading or transforming document contents. ConfigKit
|
||||
would still perform all placement and composition. Directory basenames do not
|
||||
implicitly identify namespaces, and filenames do not identify resources.
|
||||
Directly selected fragments with `Input.Destination` remain possible. Entry
|
||||
imports are the recommended packaging convention because publishers can describe
|
||||
their layout. Filenames and directory basenames do not define resource identity;
|
||||
no implicit directory discovery, namespace inference, or collection installer is
|
||||
introduced. A helper may construct inputs from explicit source selections but
|
||||
must not inspect manifests to compute their destinations.
|
||||
|
||||
Recommend explicit source selection through the ConfigKit input API first.
|
||||
PromptKit's directory helpers can enumerate files and attach a destination to
|
||||
each input once that API exists. A YAML import destination could expose the
|
||||
same operation later or alongside it; its concrete spelling is an upstream
|
||||
decision. This proposal does not claim that existing `configkit.imports`
|
||||
directives accept a destination today.
|
||||
Use later underlay groups or main for intentional application/operator overrides.
|
||||
Placement does not establish precedence. Do not also recursively scan files
|
||||
already selected by entry imports: ConfigKit's repeated-source rules still apply.
|
||||
|
||||
Put peer collection inputs in one strict underlay group. Use later groups or
|
||||
main for intentional application/operator overrides. Selecting a destination
|
||||
does not select a precedence tier. Avoid loading the same files both through
|
||||
a recursive whole-collection scan and through the individual mounted folders.
|
||||
The entry's source-root `version` is checked and consumed before its payload
|
||||
composes. Its `release_version` is retained as ordinary collection metadata.
|
||||
A prompt's nested optional `version` is also ordinary payload. These are three
|
||||
distinct concepts; source-root release metadata must no longer use `version`.
|
||||
|
||||
The assembled application shape would be equivalent to:
|
||||
|
||||
@@ -146,7 +178,7 @@ The assembled application shape would be equivalent to:
|
||||
version: 1
|
||||
collections:
|
||||
weatherreporter:
|
||||
version: "2.4.0"
|
||||
release_version: "2.4.0"
|
||||
prompts:
|
||||
summarize.alerts:
|
||||
version: "1"
|
||||
@@ -185,15 +217,16 @@ it is not a PromptKit resource identifier.
|
||||
|
||||
One fragment may contain several local definitions. A fragment starting directly
|
||||
with `messages:` would need a destination that also supplies the local prompt
|
||||
key. Generic mounting could permit that, but recommend the local-key mapping
|
||||
above as the standard authoring form: identity travels with the definition and
|
||||
files may be reorganized without changing it. Filename-derived IDs are not
|
||||
key. ConfigKit mounting permits such placement, but with source checks enabled
|
||||
its root `version` would be the specification header, not prompt metadata. Recommend
|
||||
the local-key mapping above as the standard authoring form: identity travels
|
||||
with the definition and files may be reorganized without changing it. Filename-derived IDs are not
|
||||
needed.
|
||||
|
||||
## Final Schema And Identity
|
||||
|
||||
Recommend `collections` as a mapping of namespace to collection body, containing
|
||||
optional release `version` and optional `backends`, `profiles`, and `prompts`
|
||||
optional `release_version` and optional `backends`, `profiles`, and `prompts`
|
||||
mappings. Collection release labels are descriptive, with no SemVer ordering
|
||||
or dependency-solving semantics. Metadata is optional: an installed collection
|
||||
can contain resources without claiming a published release.
|
||||
@@ -244,47 +277,27 @@ 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.
|
||||
|
||||
## Required ConfigKit Mount Semantics
|
||||
## ConfigKit Composition Boundary
|
||||
|
||||
The upstream feature should be generic source placement, not a PromptKit-aware
|
||||
collection loader or application callback that transforms source documents.
|
||||
The following is the recommended contract to agree and test upstream:
|
||||
Use the implemented upstream contracts without duplicating them in PromptKit.
|
||||
Input destinations use literal mapping-key segments, independent of filesystem
|
||||
roots and precedence. Relative import destinations are sequences of strings;
|
||||
omission and `[]` retain the importing destination. Null, scalar, and non-string
|
||||
destination members are invalid. No logical path segment means parent traversal
|
||||
or a reset to the application root.
|
||||
|
||||
1. An input has an optional destination of literal mapping-key segments. An
|
||||
empty destination preserves existing root behavior. It is independent of
|
||||
the filesystem path, filesystem containment root, and precedence group.
|
||||
2. ConfigKit parses each source with its existing YAML rules and processes
|
||||
source-root directives before placing application content at its destination.
|
||||
Synthetic mapping ancestors participate in ordinary composition. It does
|
||||
not turn dots or slashes inside a generic key into path separators.
|
||||
3. Imports without an explicit destination inherit the importing input's
|
||||
destination. If import placement is exposed, recommend its destination be
|
||||
relative to the importing destination. Explicitly selected independent
|
||||
inputs use root-relative destinations. This keeps a mounted import subtree
|
||||
contained in its declared configuration context without guessing filenames.
|
||||
4. Placement precedes strict composition and layer assembly. Contributions to
|
||||
the same destination obey the existing mapping rules; conflicts with scalar
|
||||
ancestors use those same strict-versus-overlay rules. No new merge, deletion,
|
||||
or whole-definition replacement operation is implied.
|
||||
5. Origins and diagnostics retain physical source locations and explain their
|
||||
effective destination paths. Synthesized ancestors must not obscure the
|
||||
contributing source. Resource contexts remain attached to the declaring
|
||||
source: mounting does not relocate relative `content_file` references.
|
||||
6. Apply protected specification-path checks to the destination-adjusted
|
||||
application paths. A release `version` mounted at
|
||||
`[collections, weatherreporter]` is not the protected root `version`.
|
||||
Contributions that actually reach or replace the protected path remain
|
||||
forbidden. Main's version checker still runs at its established stage;
|
||||
mounting does not grant fragments their own compatibility checks.
|
||||
7. Preserve source cycle/repetition, acquisition, and budget rules. Mounting
|
||||
must not silently authorize loading the same physical source twice within
|
||||
a group. Account for synthesized ancestors and destination depth within
|
||||
ConfigKit's limits. Existing unmounted loads retain their behavior.
|
||||
Source-root import directives remain structural. Imported content contributes at
|
||||
its resulting destination, while physical import paths and `content_file` bases
|
||||
remain relative to their declaring sources. `SourceInfo.Destination` records
|
||||
placement; normal origins and diagnostics retain real source locations. Selected
|
||||
overlays and explicit CLI overrides remain rooted at the application root.
|
||||
|
||||
Item 6 is a necessary upstream change, not something PromptKit can work around
|
||||
by stripping a source header. Agree its interaction with imports and main's
|
||||
version protection explicitly. Mounting main away from the root is unnecessary
|
||||
for this PromptKit standard.
|
||||
Mounting preserves source identity, cycle/repetition rules, and load limits.
|
||||
An absent `NoSource` contributes no payload; an actual empty mapping can
|
||||
materialize its destination containers without clearing lower contents.
|
||||
ConfigKit's reserved structural keys continue to apply. PromptKit must not
|
||||
strip headers, re-key source trees, merge fragments itself, or turn source
|
||||
inspection into an additional enforcement pass.
|
||||
|
||||
### Composition And Overrides
|
||||
|
||||
@@ -324,32 +337,92 @@ before selecting a migration plan.
|
||||
|
||||
## Specification Versions And Collection Inventory
|
||||
|
||||
Keep `version: 1` at the application root for the candidate PromptKit
|
||||
specification, checked through ConfigKit's version mechanism. It describes
|
||||
the assembled schema, independently of collection release and prompt labels.
|
||||
The three proposals are competing candidate formats, not interchangeable
|
||||
released meanings of specification version 1.
|
||||
### Shared Specification Policy
|
||||
|
||||
Mounting alone does not solve independent collection compatibility checking.
|
||||
A mounted `collection.yml` containing a release `version` does not declare or
|
||||
validate a separate specification version. A self-contained collection entry
|
||||
document with its own specification header would need a further ConfigKit
|
||||
contract for checking and consuming that header before mounting its payload.
|
||||
Do not infer compatibility from a directory name or release label, or have
|
||||
PromptKit load and validate each manifest separately. Keep that upstream
|
||||
extension open rather than bundling it implicitly into source placement.
|
||||
Use one `Definition.Version` policy, with source-local path `version`, for the
|
||||
candidate PromptKit specification. Initially accept specification text `1` from
|
||||
string or strict decimal-integer declarations; reject explicit null and other
|
||||
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.
|
||||
|
||||
Recommend collection inventory derived from the final `collections` mapping:
|
||||
namespace plus optional effective release label, sorted and detached from the
|
||||
captured engine. Metadata-only and resource-only entries can both appear.
|
||||
Root unqualified resources do not invent a named collection. Resource-based
|
||||
namespace enumeration remains a separate listing operation.
|
||||
The selected initial direction is `SourceVersionModeIfPresent`:
|
||||
|
||||
An inventory reports effective configuration declarations, not immutable
|
||||
package identity, historical source ownership, or proof of unchanged published
|
||||
contents. Operator overrides may alter resources while leaving a release
|
||||
label in place. Source explanations remain ConfigKit inspection concerns.
|
||||
Engine construction captures configuration; edits require a replacement engine.
|
||||
| Mode | Implemented behavior | Role in this proposal |
|
||||
| --- | --- | --- |
|
||||
| `Default` | Existing main-only effective-path check and protected-path behavior | Not the proposed shared-source policy |
|
||||
| `IfPresent` | Checks present declarations; skips absent non-main declarations | Initial choice for compact fragments |
|
||||
| `Required` | Requires declarations on every participating document | Possible stricter consumer option; not entry-only checking |
|
||||
|
||||
Participating documents include actual main and underlay inputs, transitive and
|
||||
glob imports, and the selected overlay. Defaults, synthetic CLI overrides,
|
||||
resolution output, absent optional imports, and empty groups do not need headers.
|
||||
Explicit null is present and reaches the checker; malformed selected values
|
||||
fail ConfigKit's version-type validation. A rejected declaration fails loading
|
||||
even if a higher layer would supersede that source's payload.
|
||||
|
||||
In enabled modes, accepted non-main headers are consumed before composition.
|
||||
The main declaration remains and is protected at its destination-prefixed path.
|
||||
PromptKit's recommended main is unmounted, so that protected path is `/version`.
|
||||
Do not confuse header consumption with permission to override the remaining
|
||||
protected application field.
|
||||
|
||||
`IfPresent` does not require a collection entry header and does not infer a
|
||||
fragment's compatibility from its entry. It checks the declarations actually
|
||||
present. Requiring headers only on entry files is not supported by the load-wide
|
||||
mode. Do not emulate it using a preliminary manifest load or validation of
|
||||
source history. If that stronger guarantee becomes essential, seek an explicit
|
||||
upstream contract instead.
|
||||
|
||||
### Naming And Optional Main Inputs
|
||||
|
||||
Reserve source-root `version` for specification declarations throughout the new
|
||||
format. Use `release_version` for optional collection release labels and retain
|
||||
nested prompt `version` for the optional installed-prompt label. An old release
|
||||
file containing only `version: "2.4.0"` can fail the specification check; if its
|
||||
text happens to be accepted, that field is consumed and lost as release metadata.
|
||||
Migration must rename it rather than simply enable the new mode.
|
||||
|
||||
This reservation affects resource fragments whose local key is literally
|
||||
`version`: a root mapping with that name is interpreted as a malformed header.
|
||||
Recommend expressing such a resource within a nested resource mapping in the
|
||||
collection entry, for example `prompts: {version: ...}`, rather than globally
|
||||
banning that public resource ID. The exact author-facing convention remains
|
||||
open below. Existing `configkit` and `extends` structural reservations also
|
||||
remain applicable; destinations do not bypass them.
|
||||
|
||||
An absent header in an actual main document still reaches the checker under
|
||||
`IfPresent`. `NoSource` also invokes the existing absent-main checker behavior,
|
||||
even under `Required`. Consequently, the mode alone does not determine whether
|
||||
PromptKit supports construction without a main declaration. Recommend an
|
||||
explicit main specification declaration for the new standard, including for a
|
||||
programmatically supplied main, without silently injecting one. An alternative
|
||||
is to accept absent main declarations deliberately for underlay-only callers;
|
||||
settle that compatibility choice before implementing the checker.
|
||||
|
||||
### Inspection And Effective Collection Inventory
|
||||
|
||||
`SourceInfo.VersionCheck` is source evidence, not a generic success flag. A
|
||||
non-nil record with `Present == false` can describe an omission for which the
|
||||
checker did not run. Header paths and locations are source-local. Evidence is
|
||||
detached and does not reread inputs; text is conservatively redacted during
|
||||
callbacks and on failed loads, and successful final records respect completed
|
||||
sensitivity classification. These records belong in explicit configuration
|
||||
inspection, not in ordinary domain validation or collection-release identity.
|
||||
|
||||
Derive collection inventory from the final `collections` mapping: namespace
|
||||
plus optional effective `release_version`, sorted and detached from the captured
|
||||
engine. Metadata-only and resource-only entries can both appear. Root unqualified
|
||||
resources do not invent a named collection; resource-based namespace enumeration
|
||||
remains separate. Exact exported inventory types remain API design work.
|
||||
|
||||
An inventory describes effective configuration, not immutable package identity,
|
||||
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
|
||||
|
||||
@@ -360,10 +433,11 @@ Engine construction captures configuration; edits require a replacement engine.
|
||||
| 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 |
|
||||
| Main upstream change | None | Record composition and inheritance | Source placement, provenance, and adjusted path protection |
|
||||
| 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 |
|
||||
| Independent collection specification check | Unavailable | Unavailable | Still a separate extension |
|
||||
| Source specification checks as described | Main only | Main only | Shared policy; non-main declarations checked when present |
|
||||
|
||||
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
|
||||
@@ -374,9 +448,12 @@ Migration must choose one installed definition for each former multi-version
|
||||
prompt, move any retained version into its optional field, and relocate
|
||||
qualified resource keys into collection/local-key mappings. Update destination
|
||||
declarations, stored references, request-version handling, inventories, and
|
||||
configuration-inspection paths. Preserve provider model strings and source
|
||||
resource bases. Namespace mounting does not automatically relocate schema or
|
||||
artifact stores or rewrite references when a collection is renamed.
|
||||
configuration-inspection paths. Rename collection release metadata to
|
||||
`release_version`, configure the shared checker and mode, and account for the
|
||||
source-root header reservation and the selected main-absence policy. Preserve
|
||||
provider model strings and source resource bases. Namespace mounting does not
|
||||
automatically relocate schema or artifact stores or rewrite references when a
|
||||
collection is renamed.
|
||||
|
||||
Retain the accepted removal of mandatory catalog modules and built-in profiles.
|
||||
This is a breaking configuration/API change under the
|
||||
@@ -384,50 +461,70 @@ This is a breaking configuration/API change under the
|
||||
migration guidance and update current contracts when it lands. The proposal
|
||||
does not change today's supported configuration or API.
|
||||
|
||||
## Delivery, Validation, And Remaining Decisions
|
||||
## Delivery And Validation
|
||||
|
||||
Agree and implement the generic mount contract in ConfigKit first, then adopt
|
||||
it in PromptKit's source helpers and final-configuration adapter. Build qualified
|
||||
runtime indexes only after handoff. Keep collection installation, remote
|
||||
fetching, automatic directory discovery, live reload, and dependency solving
|
||||
outside this work.
|
||||
Select a released ConfigKit dependency containing the reviewed capabilities,
|
||||
then implement PromptKit's schema, source-selection convenience APIs, and final
|
||||
configuration adapter. Do not use a committed filesystem replacement as the
|
||||
release integration. Build qualified runtime indexes after handoff. Collection
|
||||
installation, remote fetching, implicit discovery, live reload, identity-based
|
||||
list composition, and dependency solving remain outside this work.
|
||||
|
||||
Upstream acceptance should exercise root and nested placement; overlapping
|
||||
destinations within strict groups and across layers; mounted nested imports;
|
||||
source cycles/repetition; destination-aware protected-version checks; source
|
||||
locations and resource bases; sibling inheritance; and unchanged unmounted
|
||||
behavior. Verify mounted metadata cannot bypass root version protection.
|
||||
PromptKit acceptance should exercise typed assembly of multiple collections,
|
||||
relative/nested imports, source-local header checking and consumption, ordinary
|
||||
release and prompt metadata, unqualified resources, scoped selection, optional
|
||||
prompt versions, inventory without release metadata, source-relative content,
|
||||
intentional partial overrides, and the chosen main-absence policy. Add request
|
||||
version assertions if retained. Do not duplicate ConfigKit's generic source
|
||||
validation or enforce domain rules through historical source inspection.
|
||||
|
||||
PromptKit acceptance should cover the illustrated assembled tree, same local
|
||||
names in different collections, unqualified resources, scoped selection,
|
||||
versioned and unversioned prompts, explicit version assertions if retained,
|
||||
inventory without release metadata, source-relative message content, and
|
||||
intentional partial overrides. Do not add per-source PromptKit validation.
|
||||
Review verification on 2026-10-16 against ConfigKit `e66c371`: focused public API
|
||||
and consumer-example tests passed. A temporary typed consumer also passed
|
||||
combined assembly for two collections with equal local prompt names, nested
|
||||
relative imports and content-file contexts, optional prompt versions, both
|
||||
enabled header modes, rejected headers despite upper-layer overrides, and
|
||||
migration behavior for old release fields. The temporary consumer lives outside
|
||||
both repositories. An additional offline check assembled this document's YAML
|
||||
fragments through entry imports and matched the illustrated effective tree;
|
||||
local links and whitespace checks passed. These checks verify upstream behavior
|
||||
and the candidate schema, not an implemented PromptKit engine feature.
|
||||
|
||||
Review verification on 2026-10-14: a temporary offline consumer of the local
|
||||
ConfigKit checkout decoded all six YAML examples into generic mappings and
|
||||
confirmed that a version-only overlay preserves the lower prompt body. Local
|
||||
documentation links and whitespace checks passed. These checks establish the
|
||||
current YAML and mapping behavior, not the unimplemented mount extension or
|
||||
future PromptKit schema. The temporary consumer is outside both repositories.
|
||||
## Remaining PromptKit Decisions
|
||||
|
||||
The remaining decisions are:
|
||||
The agreed direction uses the implemented mount/import APIs, a shared
|
||||
specification policy with `IfPresent`, and distinct `release_version` metadata.
|
||||
These are no longer pending upstream feature requests. The following choices
|
||||
remain before the PromptKit contract is complete:
|
||||
|
||||
- **Mount API and packaging:** prefer an input destination plus a conventional
|
||||
explicitly selected directory layout. An import-destination directive would
|
||||
let publishers express more assembly in configuration; settle its syntax
|
||||
upstream. A manifest that computes its own mount from a declared namespace
|
||||
would require further ConfigKit semantics and is not assumed here.
|
||||
- **Cross-collection inheritance:** prefer existing local sibling inheritance
|
||||
initially; add generic path references upstream if migration needs justify
|
||||
the added contract.
|
||||
- **Request versions:** prefer optional exact assertions for migration; removing
|
||||
version selectors is simpler if consumers do not need that guard.
|
||||
- **Independent specification headers:** keep one main-owned declaration for
|
||||
this proposal; pursue a distinct ConfigKit extension if collections must
|
||||
each assert compatibility independently.
|
||||
1. **Main declaration:** recommend requiring an explicit supported declaration
|
||||
in a real or programmatic main input. Alternatively, accept absent main for
|
||||
existing underlay-only callers, with the weaker guarantee documented. Neither
|
||||
option follows automatically from ConfigKit's mode, and no version should be
|
||||
silently injected.
|
||||
2. **Public mode selection:** use `IfPresent` initially. Decide whether callers
|
||||
may opt into `Required` through PromptKit's source configuration API. Exposing
|
||||
it gives deployments an all-document declaration requirement; keeping one
|
||||
initial mode reduces API surface. It cannot mean entry-only enforcement.
|
||||
3. **Reserved header naming:** recommend allowing a local resource ID `version`
|
||||
through nested mappings in the entry document while reserving source-root
|
||||
`version` for the specification. Alternatively, reserve that resource name
|
||||
in the new format for a uniform fragment convention, at the cost of a new ID
|
||||
restriction. Do not let an incidental parser limitation silently decide it.
|
||||
4. **Request versions:** recommend retaining optional exact assertions against
|
||||
the one installed prompt's label. Removing request-side version fields is
|
||||
simpler if consumers do not need this compatibility guard. Also finalize the
|
||||
proposed absent/null/nonblank-string rules and listing representation.
|
||||
5. **Cross-collection inheritance:** recommend local sibling inheritance and
|
||||
flattening authored cross-collection bases for the initial migration.
|
||||
Request generic cross-path inheritance upstream only if concrete catalog
|
||||
migration needs justify it; do not resolve it inside PromptKit.
|
||||
6. **Consumer API and packaging:** recommend an explicitly selected entry path
|
||||
and namespace, with publisher-owned relative imports and one peer group.
|
||||
Finalize the helper signatures, conventional entry filename, inventory types,
|
||||
and migration examples. Direct mounted fragments remain a useful alternative
|
||||
for applications that already assemble sources themselves.
|
||||
|
||||
These recommendations are reviewable choices, not claims that upstream work
|
||||
has been accepted. One installed definition and an optional prompt version are
|
||||
the settled requirements for this alternative. The parent configuration
|
||||
decision remains open while the three proposals are compared.
|
||||
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.
|
||||
|
||||
@@ -492,10 +492,13 @@ 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.
|
||||
All three retain main-owned specification versioning; independent collection
|
||||
checks remain a separate upstream question. These are proposals for comparison;
|
||||
this decision remains open. Proposal 3 deliberately revises the version-selection
|
||||
and listing assumptions elsewhere in this roadmap if that alternative is adopted.
|
||||
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.
|
||||
|
||||
**Desired capability:** describe collection namespace and release version in
|
||||
configuration and expose an API through which downstream applications can list
|
||||
|
||||
Reference in New Issue
Block a user