Clarify collection contracts and migration docs

This commit is contained in:
2026-10-17 06:35:56 +00:00
parent 29f104fbc0
commit dfd8da843e
16 changed files with 236 additions and 102 deletions

View File

@@ -28,8 +28,10 @@ namespace-filtered discovery, without contacting a provider or requiring
credentials. credentials.
The [consumer guide](docs/consumers/pkg-promptkit.md) also shows a local backend, The [consumer guide](docs/consumers/pkg-promptkit.md) also shows a local backend,
ordered file/embedded sources, programmatic mappings, and how to replace an ordered file/embedded sources, programmatic mappings, and how to replace an
engine when source files change. Read the engine when source files change. Applications adapting the prior keyed
[example source](examples/go-library/prepare/main.go), the configuration or versioned-prompt format can consult the
[configuration migration guide](docs/consumers/configuration-migration.md).
See the [example source](examples/go-library/prepare/main.go), the
[Go package consumer guide](docs/consumers/pkg-promptkit.md), and the [Go package consumer guide](docs/consumers/pkg-promptkit.md), and the
[framework format reference](docs/formats.md) to build a consumer workflow. [framework format reference](docs/formats.md) to build a consumer workflow.
The consumer guide also covers explicit, live smoke diagnostics and interpreting The consumer guide also covers explicit, live smoke diagnostics and interpreting

View File

@@ -13,9 +13,10 @@ import (
) )
// CollectionInput mounts source at the selected collection's configuration // CollectionInput mounts source at the selected collection's configuration
// destination and enables ConfigKit imports for that input. The source is not // destination, collections/<namespace>, and enables ConfigKit imports for that
// read or validated until ConfigKit loads it. Callers may adjust the returned // input. An invalid namespace returns an error matching ErrInvalidConfig. The
// input, including its filesystem context or imports setting. // source is not read or validated until ConfigKit loads it. Callers may adjust
// the returned input, including its filesystem context or imports setting.
func CollectionInput(namespace string, source configkit.Source) (configkit.Input, error) { func CollectionInput(namespace string, source configkit.Source) (configkit.Input, error) {
if !domain.IsValidResourceNamespace(namespace) { if !domain.IsValidResourceNamespace(namespace) {
return configkit.Input{}, fmt.Errorf("%w: invalid collection namespace %q", ErrInvalidConfig, namespace) return configkit.Input{}, fmt.Errorf("%w: invalid collection namespace %q", ErrInvalidConfig, namespace)

View File

@@ -252,7 +252,7 @@ for _, difference := range differences {
``` ```
See the [`ConfigurationInspection.Diff` GoDoc](../../configuration_inspection.go) See the [`ConfigurationInspection.Diff` GoDoc](../../configuration_inspection.go)
and ConfigKit's [v0.7.0 effective-configuration diff guidance](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.0/docs/config.md#effective-configuration-diffs) and ConfigKit's [v0.8.0 effective-configuration diff guidance](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.8.0/docs/config.md#effective-configuration-diffs)
for the exact comparison contract. The operation compares only frozen effective for the exact comparison contract. The operation compares only frozen effective
configuration values: it does not reread external files or compare their configuration values: it does not reread external files or compare their
contents, resolved credential contents, later execution preparation, or contents, resolved credential contents, later execution preparation, or
@@ -637,24 +637,16 @@ are keys in configuration, not registrations. Choose caller underlays in
fallback-to-operator-to-programmatic order; use `Sources.Main` for one final fallback-to-operator-to-programmatic order; use `Sources.Main` for one final
highest-priority input. highest-priority input.
Move embedded `id` and `version` fields into keyed `profiles` and `prompts` Move embedded IDs into keyed `profiles` and `prompts` maps; each prompt ID now
maps; convert `base_profile` to ConfigKit `extends`. IDs and references are contains one installed definition, with any descriptive `version` label inside
exact literal keys, without trimming. A supplied zero, false, or empty string that definition. Convert `base_profile` to ConfigKit `extends`. For the current
is now distinguishable from omission; null can clear or suppress an inherited collection identity mapping, ID-only prompt selection, and required
field according to the [field table](../formats.md#defaults-and-overrides). caller-owned choices, see the
Maps merge recursively across inheritance and layers. `{}` does not clear an [configuration migration guide](configuration-migration.md). Exact current
inherited map: use null to clear the whole map. At request time, a literal format, reference, inheritance, and presence semantics belong to the
`extra_params["extends"]` is ordinary provider data, not an inheritance [framework format reference](../formats.md). Prompt text and static templates
instruction; a nonempty request ExtraParams map replaces configured params. are captured at construction, not automatically reloaded between runs. Replace
Changing a model or backend does not clear unrelated explicit fields, though the engine to pick up changed definitions or message files.
backend-derived defaults are applied after inheritance to the final backend.
Invalid final definitions, including unused ones, now fail `NewEngine`; only
request-dependent failures remain at preparation or execution. Prompt text
and static templates are captured at construction, not automatically reloaded
between runs. Replace the engine to pick up changed definitions or message
files. The [format reference](../formats.md) owns exact field and presence
rules; the maintained examples show complete runnable workflows.
### Choose A Profile Ownership Model ### Choose A Profile Ownership Model
@@ -662,8 +654,9 @@ Supply backend and profile definitions through the configuration sources your
application selects. PromptKit does not install provider catalogs or built-in application selects. PromptKit does not install provider catalogs or built-in
profile inventories; conventional backend ID constants are names only. Define profile inventories; conventional backend ID constants are names only. Define
the model, endpoint, credentials lookup, and settings that your application the model, endpoint, credentials lookup, and settings that your application
intends to support. Profiles may inherit another configured profile using an intends to support. A profile may inherit a sibling profile by its local key in
exact ID, and caller-selected source layers determine the final values. The the same root or collection mapping; its backend reference uses the exact
configured identity. Caller-selected source layers determine the final values. The
[format reference](../formats.md) describes the definition fields and [format reference](../formats.md) describes the definition fields and
composition rules. composition rules.

View File

@@ -10,12 +10,14 @@ owns outbound wire behavior. [ConfigKit](https://gitea.maximumdirect.net/eric/Co
owns the generic YAML grammar, imports, layering, inheritance, and diagnostics. owns the generic YAML grammar, imports, layering, inheritance, and diagnostics.
This reference describes what Promptkit does with the final effective values. This reference describes what Promptkit does with the final effective values.
A configuration document has keyed top-level `backends`, `profiles`, and A configuration document may contain keyed top-level `backends`, `profiles`,
`prompts` mappings. Their keys are literal IDs, not filename-derived identities. and `prompts` mappings, plus a `collections` mapping of namespaced resource
Each prompt ID maps directly to one definition; an optional `version` string is groups. Resource keys are literal IDs, not filename-derived identities. Each
prompt ID maps directly to one definition; an optional `version` string is
descriptive metadata, not a selection key. Keys and references must be nonblank descriptive metadata, not a selection key. Keys and references must be nonblank
and remain exact: Promptkit does not trim or re-key them. Old embedded `id` and and remain exact: Promptkit does not trim or re-key them. Old embedded `id` and
`base_profile` fields are invalid. Unknown fields are errors. `base_profile` fields are invalid. Unknown fields are errors. Promptkit installs
no provider or profile catalog; callers select the definitions they need.
```yaml ```yaml
backends: backends:
@@ -36,8 +38,66 @@ prompts:
output: output:
format: text format: text
validation_mode: none validation_mode: none
collections:
support:
release_version: "1.4.0"
backends:
offline:
endpoint: https://example.invalid/v1
profiles:
base:
backend: support/offline
model: offline-model
fast:
extends: base
timeout_seconds: 30
prompts:
answer:
default_profile: support/fast
messages:
- role: user
content: Answer the selected caller input.
output:
format: text
validation_mode: none
``` ```
## Source Headers, Collections, And Resource IDs
An input may omit a source header. When present, the source-root `version` is
reserved for ConfigKit's specification header and accepts only the exact string
`"1"` or strict decimal integer `1`; null and other values are invalid. This
header is distinct from a prompt's nested `version` label and a collection's
`release_version`. ConfigKit checks and consumes accepted headers on non-main
inputs; a declaration on the main input remains visible in explicit
configuration inspection. Headerless inputs still undergo ordinary final-value
validation. ConfigKit owns generic import and source-history behavior.
The root resource mappings contain unqualified IDs. Each `collections` entry
has a namespace key and may contain `release_version` plus the same three
resource mappings. Collection resource keys are local keys; their runtime IDs
are `<namespace>/<local-key>`. Root and collection keys may be the same. A
namespace and local key must be nonblank and slash-free, and references must
name their intended exact ID; mounting a source does not rewrite references.
For example, the `support/fast` profile above stores `support/offline` as its
backend ID. In `collections.support.profiles.fast`, ConfigKit `extends: base`
refers to a sibling profile in that same mapping. It is not a qualified or
cross-collection reference.
`release_version` and prompt `version` are optional opaque labels. Absent or
null means no label; an explicitly empty string is retained as a declared
label. Neither label selects a resource or changes execution. Runtime lookups
use the captured effective resource indexes. `InspectConfiguration` is an
explicit operator view of effective settings and provenance; source history is
not a second runtime resolver, and the retained effective shape is not flattened
or rewritten into those indexes.
For examples of explicitly selecting native collection inputs and inspecting
inventories, see the [consumer guide](consumers/pkg-promptkit.md) and its
[maintained preparation example](../examples/go-library/prepare/main.go). For
breaking identity and prompt-selection changes, see the
[configuration migration guide](consumers/configuration-migration.md).
Every effective backend, profile, and prompt definition is validated when Every effective backend, profile, and prompt definition is validated when
`NewEngine` constructs the engine, even if it is never selected. A profile may `NewEngine` constructs the engine, even if it is never selected. A profile may
be partial: an endpoint and model need only be complete after request overrides be partial: an endpoint and model need only be complete after request overrides
@@ -282,20 +342,25 @@ An explicitly selected missing/unreadable root fails; an empty root contributes
nothing. Imports are disabled by these helpers unless the caller enables them nothing. Imports are disabled by these helpers unless the caller enables them
on an input. Single files can use ConfigKit inputs directly. on an input. Single files can use ConfigKit inputs directly.
Backends, profiles, and prompts all follow these same source rules. A later Root backends, profiles, and prompts, as well as collection declarations and
profile or backend can change individual fields of a lower definition. A their resource mappings, follow these same source rules. `CollectionInput`
request `ProfileID` takes precedence over a prompt `default_profile`; if mounts one explicitly selected source at a collection destination and enables
ConfigKit imports for that input; it does not discover or select sources.
A later profile or backend can change individual fields of a lower definition.
A request `ProfileID` takes precedence over a prompt `default_profile`; if
neither is selected, preparation fails. Exact profile inspection selects one neither is selected, preparation fails. Exact profile inspection selects one
explicit ID and does not consult a prompt default. explicit ID and does not consult a prompt default.
### Profile Inheritance ### Profile Inheritance
ConfigKit resolves `extends` on effective profile definitions. One profile ConfigKit resolves `extends` on effective profile definitions. One profile
may inherit another keyed profile; presence, explicit null, and recursively may inherit a sibling profile by local key in the same root or collection
merged maps determine the final fields. References are literal IDs, including mapping; collection inheritance cannot cross namespaces. Presence, explicit
IDs containing punctuation. There is no Promptkit-specific depth limit or null, and recursively merged maps determine the final fields. Other resource
second base-chain resolver. Missing references and cycles fail at construction. references are exact IDs and use their qualified form when they select a
For generic inheritance and layer mechanics, consult collection resource. There is no Promptkit-specific depth limit or second
base-chain resolver. Missing references and cycles fail at construction. For
generic inheritance and layer mechanics, consult
[ConfigKit](https://gitea.maximumdirect.net/eric/ConfigKit). [ConfigKit](https://gitea.maximumdirect.net/eric/ConfigKit).
## Schemas ## Schemas

View File

@@ -23,6 +23,10 @@ callback. The caller supplies normalized failure metadata; the recorder never
parses an error string or receives provider bodies, credentials, headers, or parses an error string or receives provider bodies, credentials, headers, or
other content. Events are values with no mutable containers. Callback panics other content. Events are values with no mutable containers. Callback panics
propagate to the caller. propagate to the caller.
Resolved prompt and profile IDs are the exact runtime identities selected for
the invocation, including namespace qualification when supplied by an engine
view. A prompt's optional version label is descriptive metadata, not a
selection key.
Per-operation callbacks are ordered and synchronous; different operations may Per-operation callbacks are ordered and synchronous; different operations may
invoke the same callback concurrently. The recorder marks each measured phase's invoke the same callback concurrently. The recorder marks each measured phase's
end before delivery, so callback work does not inflate provider duration. end before delivery, so callback work does not inflate provider duration.

View File

@@ -11,12 +11,12 @@ contributor workflow and validation.
| Component | Implemented responsibility | References | | Component | Implemented responsibility | References |
| --- | --- | --- | | --- | --- | --- |
| Root `promptkit` package | Provides the supported engine facade, ConfigKit source helpers, profile and backend mapping conveniences, injection options, public requests and results, prompt/profile/requirement inspection and identity listing, concrete-request validation, explicit smoke diagnostics, observation values, opaque prepared-execution handles, value conversion, redacted formatting, and typed capacity and generation error mapping. | [Package GoDoc](../../doc.go), [observations](../../observations.go), [prepared execution](../../prepared_execution.go), [backend API](../../backends.go), [engine facade](../../engine.go), [smoke diagnostics](../../smoke_diagnostics.go), [identity listing](../../listing.go), [requirement facade](../../requirements.go) | | Root `promptkit` package | Provides the supported engine facade, ConfigKit source helpers, collection and resource mapping conveniences, injection options, public requests and results, prompt/profile/requirement inspection and identity inventories, concrete-request validation, explicit smoke diagnostics, observation values, opaque prepared-execution handles, value conversion, redacted formatting, and typed capacity and generation error mapping. | [Package GoDoc](../../doc.go), [observations](../../observations.go), [prepared execution](../../prepared_execution.go), [backend API](../../backends.go), [engine facade](../../engine.go), [smoke diagnostics](../../smoke_diagnostics.go), [identity listing](../../listing.go), [requirement facade](../../requirements.go) |
| `examples/go-library/prepare` | Demonstrates offline preparation and explicit configuration inspection with a prompt file, programmatic profile, and inline input. It is not a public library package. | [Example program](../../examples/go-library/prepare/main.go) | | `examples/go-library/prepare` | Demonstrates offline preparation from two explicitly selected synthetic collections, source-relative imported content, a scoped view, filtered listings, and operator inventory. It is not a public library package. | [Example program](../../examples/go-library/prepare/main.go), [collection inputs](../../examples/go-library/prepare/collections/support/collection.yaml) |
| `examples/go-library/run` | Demonstrates an offline downstream consumer using a prompt file, programmatic profile, inline input, an injected deterministic model client, and `Run`. It is not a public library package. | [Example program](../../examples/go-library/run/main.go) | | `examples/go-library/run` | Demonstrates an offline downstream consumer using a prompt file, programmatic profile, inline input, an injected deterministic model client, and `Run`. It is not a public library package. | [Example program](../../examples/go-library/run/main.go) |
| `examples/go-library/observe` | Demonstrates offline built-in HTTP retry and synchronous metadata observation across structured proposal and assessment runs using embedded sources, two profiles on one finite backend, and an application decision. It is not a public library package. | [Example program](../../examples/go-library/observe/main.go) | | `examples/go-library/observe` | Demonstrates offline built-in HTTP retry and synchronous metadata observation across structured proposal and assessment runs using embedded sources, two profiles on one finite backend, and an application decision. It is not a public library package. | [Example program](../../examples/go-library/observe/main.go) |
| `internal/backend` | Holds a defensive, immutable lookup of final backend definitions, including diagnostic metadata, plus capacity policies validated by the configuration adapter. | [Backend registry](../../internal/backend/registry.go) | | `internal/backend` | Holds a defensive, immutable lookup of final backend definitions, including diagnostic metadata, plus capacity policies validated by the configuration adapter. | [Backend registry](../../internal/backend/registry.go) |
| `internal/configuration` | Loads keyed backend, profile, and prompt configuration through ConfigKit; records effective field presence, validates final values including optional diagnostic metadata, captures indexed prompt definitions, referenced message content, compiled templates, input metadata snapshots, sorted identity-only backend, profile, and prompt inventories, resource namespace sets, effective collection declarations, backend and presence-aware profile snapshots, and an explicit read-only inspection view. | [Typed loader](../../internal/configuration/load.go), [identity listing](../../internal/configuration/listing.go), [internal sources](sources.md#typed-configuration-loading) | | `internal/configuration` | Loads root and namespaced collection resources through ConfigKit; records effective field presence, validates final values including exact references and optional diagnostic metadata, captures indexed prompt definitions and source-relative message content, compiled templates, input metadata snapshots, sorted backend/profile/prompt identities, resource namespace sets, effective collection declarations, backend and presence-aware profile snapshots, and the unchanged read-only inspection view. | [Typed loader](../../internal/configuration/load.go), [identity listing](../../internal/configuration/listing.go), [internal sources](sources.md#typed-configuration-loading) |
| `internal/capacity` | Owns engine-local bounded execution admission and FIFO model-generation permits for limited backend IDs, including cancellation-safe waiter removal and client wrapping. | [Internal capacity management](capacity.md) | | `internal/capacity` | Owns engine-local bounded execution admission and FIFO model-generation permits for limited backend IDs, including cancellation-safe waiter removal and client wrapping. | [Internal capacity management](capacity.md) |
| `internal/domain` | Defines internal framework values for requests, artifacts, prompt definitions, requirement inspection, profiles, execution targets, rendering, generation, validation, and source-neutral smoke diagnostics, and owns source-neutral invariants for shared execution settings, OpenAI-compatible base endpoints, session identifiers, output contracts, and resource-identity syntax and qualification. Source parsing, required fields, other source-specific normalization, defaulting, and boundary-specific error classification remain with their callers. | [Domain declarations](../../internal/domain/domain.go), [requirement values](../../internal/domain/requirements.go), [endpoint invariant](../../internal/domain/endpoint.go) | | `internal/domain` | Defines internal framework values for requests, artifacts, prompt definitions, requirement inspection, profiles, execution targets, rendering, generation, validation, and source-neutral smoke diagnostics, and owns source-neutral invariants for shared execution settings, OpenAI-compatible base endpoints, session identifiers, output contracts, and resource-identity syntax and qualification. Source parsing, required fields, other source-specific normalization, defaulting, and boundary-specific error classification remain with their callers. | [Domain declarations](../../internal/domain/domain.go), [requirement values](../../internal/domain/requirements.go), [endpoint invariant](../../internal/domain/endpoint.go) |
| `internal/engine` | Assembles caller-selected configuration into one snapshot, then constructs shared capacity, rendering, validation, generation, repair, the ordinary runner, and the smoke tester for each engine. Immutable namespace views share those collaborators and qualify caller-supplied execution, inspection, and diagnostic selections without rewriting captured references. Built-in engines provide the diagnostic HTTP collaborator; injected-client engines do not. It delegates identity listing directly to the captured configuration inventory rather than the runner. | [Engine assembly](../../internal/engine/engine.go), [internal sources](sources.md#typed-configuration-loading), [internal runner](runner.md) | | `internal/engine` | Assembles caller-selected configuration into one snapshot, then constructs shared capacity, rendering, validation, generation, repair, the ordinary runner, and the smoke tester for each engine. Immutable namespace views share those collaborators and qualify caller-supplied execution, inspection, and diagnostic selections without rewriting captured references. Built-in engines provide the diagnostic HTTP collaborator; injected-client engines do not. It delegates identity listing directly to the captured configuration inventory rather than the runner. | [Engine assembly](../../internal/engine/engine.go), [internal sources](sources.md#typed-configuration-loading), [internal runner](runner.md) |

View File

@@ -32,6 +32,13 @@ The runner has no durable run or session store.
## Shared Prompt Selection ## Shared Prompt Selection
The internal engine applies each namespace view to slashless caller selections
before they reach the runner. The runner therefore selects captured prompts and
profiles by the resulting exact runtime IDs. Already-qualified selections pass
through, while configured defaults and stored references are used as authored
and are not requalified. Prompt version labels are returned as optional
descriptive metadata; they are not prompt selectors.
Ordinary preparation selects the full prompt definition and construction-time Ordinary preparation selects the full prompt definition and construction-time
hash. It retains its early request-ID check before direct-session hash. It retains its early request-ID check before direct-session
normalization. Referenced message content and static template syntax were normalization. Referenced message content and static template syntax were
@@ -73,10 +80,12 @@ exact contract.
## Smoke-Test Diagnostics ## Smoke-Test Diagnostics
The separate `SmokeTester` in `internal/usecase` selects from the same captured The separate `SmokeTester` in `internal/usecase` selects from the same captured
configuration snapshot and backend/profile collaborators as the runner. Explicit configuration snapshot and backend/profile collaborators as the runner. The
profile selection takes precedence over prompt-default selection and a backend internal engine applies namespace-view qualification to slashless caller IDs
diagnostic default; HTTP-only selection does not resolve a default inference before diagnostic selection; captured defaults and references remain exact.
profile. Exact public selection rules belong to the root Explicit profile selection takes precedence over prompt-default selection and a
backend diagnostic default; HTTP-only selection does not resolve a default
inference profile. Exact public selection rules belong to the root
[`Engine.SmokeTest` GoDoc](../../smoke_diagnostics.go). [`Engine.SmokeTest` GoDoc](../../smoke_diagnostics.go).
Diagnostics do not call `Run`, `Prepare`, or the prompt preparation pipeline. Diagnostics do not call `Run`, `Prepare`, or the prompt preparation pipeline.

View File

@@ -14,27 +14,41 @@ source semantics. Internal packages are not consumer APIs.
effective configuration to execution-owned definitions. It performs one effective configuration to execution-owned definitions. It performs one
layered load, captures effective presence (including explicit null), records layered load, captures effective presence (including explicit null), records
normalization and defaults through resolution, and validates all effective normalization and defaults through resolution, and validates all effective
backend, profile, and prompt values. Replaced lower-layer domain values are root and collection backend, profile, and prompt values. Replaced lower-layer
not separately validated. It builds an immutable backend index and domain values are not separately validated. It indexes root resources under
presence-aware profile targets, applying final backend defaults only after their unqualified IDs and collection resources under their full
profile inheritance. It retains ConfigKit's result privately for explicit `namespace/local-key` IDs while retaining ConfigKit's effective tree in its
inspection, not for per-run resolution. The runtime/domain packages do not authored shape. It builds an immutable backend index and presence-aware profile
depend on ConfigKit. targets, applying final backend defaults only after profile inheritance. Runtime
lookups use those final indexes and exact stored references; they do not rewrite
or resolve resources from ConfigKit source history. The runtime/domain packages
do not depend on ConfigKit.
ConfigKit owns source headers, imports, composition, and source evidence.
Promptkit does not preparse contributions: it validates the final effective
values once, captures the indexed identities and their original resource
contexts, and retains ConfigKit's result for explicit operator inspection.
Accepted non-main source headers are consumed during composition; the main
source declaration remains available in that inspection view. Prompt and
collection release labels are descriptive metadata, not selection inputs. The
[format reference](../formats.md#source-headers-collections-and-resource-ids)
owns the exact source-header and collection contracts.
The `ConfigurationInspection.Diff` facade method compares two retained results The `ConfigurationInspection.Diff` facade method compares two retained results
through a private wrapper and a narrow `internal/configuration.Diff` bridge. through a private wrapper and a narrow `internal/configuration.Diff` bridge.
The wrapper keeps `Result[document]` inside the adapter; the bridge delegates The wrapper keeps `Result[document]` inside the adapter; the bridge delegates
once to ConfigKit v0.7.0 and returns its public difference records. Comparison once to ConfigKit v0.8.0 and returns its public difference records. Comparison
uses only frozen effective values and does not reopen sources, resolve runtime uses only frozen effective values and does not reopen sources, resolve runtime
credentials, or enter the execution path. ConfigKit applies sensitivity from credentials, or enter the execution path. ConfigKit applies sensitivity from
both results; reports may still contain ordinary application data. See the both results; reports may still contain ordinary application data. See the
[consumer comparison guide](../consumers/pkg-promptkit.md#inspect-the-captured-configuration) [consumer comparison guide](../consumers/pkg-promptkit.md#inspect-the-captured-configuration)
and ConfigKit's [v0.7.0 comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.7.0/docs/config.md#effective-configuration-diffs). and ConfigKit's [v0.8.0 comparison contract](https://gitea.maximumdirect.net/eric/ConfigKit/src/tag/v0.8.0/docs/config.md#effective-configuration-diffs).
After prompt materialization and effective-profile snapshot construction, the After resource materialization and effective-profile snapshot construction, the
adapter captures lexically ordered, identity-only inventories from the final adapter captures lexically ordered identity inventories for backends, profiles,
prompt and indexed-profile maps. Its listing methods return caller-owned copies and prompts, per-kind resource namespace sets, and metadata for effective
of those inventories without consulting ConfigKit or copying definitions. collection declarations. Listing methods return caller-owned copies from those
captured values without consulting ConfigKit or copying resource definitions.
The root `DirectoryInputs` and `FilesystemInputs` helpers discover sorted YAML The root `DirectoryInputs` and `FilesystemInputs` helpers discover sorted YAML
files under an explicit root, provide resource context, and leave imports files under an explicit root, provide resource context, and leave imports
@@ -44,6 +58,16 @@ order, followed by the optional main input. The
[configuration tests](../../internal/configuration/load_test.go) exercise the [configuration tests](../../internal/configuration/load_test.go) exercise the
real loader and final-value handoff. real loader and final-value handoff.
The public `CollectionInput` helper mounts one caller-selected source at
`collections/<namespace>` and enables ConfigKit imports for that input. The
helper does not read the source; ConfigKit retains responsibility for loading,
composition, imports, and source-local resource context. Imported or inherited
`content_file` values continue resolving relative to the source that contributed
the effective field, not to a flattened runtime identity. Explicit
`InspectConfiguration` views expose the retained effective configuration and
provenance for operator review; runtime selection and inventories do not derive
from source history.
## Prompt Definitions ## Prompt Definitions
The configuration adapter indexes each prompt by exact ID, The configuration adapter indexes each prompt by exact ID,
@@ -59,7 +83,7 @@ strings, including empty strings. It closes content-file handles before
returning and retains no source capability for public inspection. returning and retains no source capability for public inspection.
Role and cache-control normalization is applied to execution-owned message Role and cache-control normalization is applied to execution-owned message
copies. ConfigKit v0.7.0 retains effective input message metadata and its copies. ConfigKit v0.8.0 retains effective input message metadata and its
resource origins; recording a sequence-wide normalization in the retained resource origins; recording a sequence-wide normalization in the retained
configuration would replace origins of unchanged content-file fields. configuration would replace origins of unchanged content-file fields.
@@ -114,8 +138,10 @@ change rendering behavior.
## Profiles ## Profiles
ConfigKit resolves profile inheritance before the handoff. The configuration ConfigKit resolves profile inheritance before the handoff. Within a collection,
adapter validates effective references and field values, then builds target `extends` names a sibling local key; it is not a cross-collection reference.
The configuration adapter validates final effective resource references and
field values, then builds target
snapshots with backend defaults and presence/suppression state. A profile can snapshots with backend defaults and presence/suppression state. A profile can
remain partial until runtime overrides complete it. `InspectProfile` selects remain partial until runtime overrides complete it. `InspectProfile` selects
that captured target without prompt, artifact, schema, credential lookup, or that captured target without prompt, artifact, schema, credential lookup, or

View File

@@ -782,6 +782,16 @@ Validation: review changed Markdown links and example references, check GoDoc
against declarations, and run `git diff --check`. Release notes and version/tag against declarations, and run `git diff --check`. Release notes and version/tag
selection belong to the later requested release preparation, not this stage. selection belong to the later requested release preparation, not this stage.
Completion: canonical format, consumer, README, internal, and public GoDoc
contracts now describe collection identity, source headers and origins,
namespace-scoped selection, global inventories, descriptive labels, and
caller-supplied provider configuration. Reviewed architecture, release policy
and procedure, development guidance, and attribution; no additional local
changes were needed, and historical release notes and immutable ADRs remain
unchanged. Validation passed: local Markdown link targets and example references
were reviewed, affected GoDoc was checked against declarations, and
`git diff --check`.
## Stage 18: Verify Cross-Boundary Behavior And Close The Sprint ## Stage 18: Verify Cross-Boundary Behavior And Close The Sprint
Scope: focused integration gaps and final regression validation, not new features. Scope: focused integration gaps and final regression validation, not new features.

View File

@@ -248,7 +248,9 @@ func NewEngine(cfg Config, opts ...Option) (*Engine, error) {
// execution work. // execution work.
// //
// InspectPrompt requires a nonblank promptID and performs an exact, // InspectPrompt requires a nonblank promptID and performs an exact,
// case-sensitive lookup in the captured configuration snapshot. // case-sensitive lookup in the captured configuration snapshot. A
// namespace-scoped view qualifies slashless caller IDs before lookup; already
// qualified IDs pass through. Prompt version labels do not select definitions.
// //
// A successful result proves that the selected definition and any referenced // A successful result proves that the selected definition and any referenced
// message content files were structurally loaded. Inputs are returned in // message content files were structurally loaded. Inputs are returned in

View File

@@ -52,8 +52,9 @@ type CollectionInfo struct {
// PromptIdentity identifies one prompt ID and its optional descriptive version // PromptIdentity identifies one prompt ID and its optional descriptive version
// label in the effective configuration captured when an Engine is constructed. // label in the effective configuration captured when an Engine is constructed.
// A nil Version means no label was declared; a non-nil empty string is an // Version is metadata only and never participates in prompt selection. A nil
// explicit label. It has no stable JSON representation. // Version means no label was declared; a non-nil empty string is an explicit
// label. It has no stable JSON representation.
type PromptIdentity struct { type PromptIdentity struct {
ID string ID string
Version *string Version *string

View File

@@ -20,8 +20,9 @@ type Namespaces struct {
// defaults on the new view and leaves the receiver unchanged; resource // defaults on the new view and leaves the receiver unchanged; resource
// existence is checked when selected. An empty field clears that resource's // existence is checked when selected. An empty field clears that resource's
// scope. Captured configuration references, defaults, and global configuration // scope. Captured configuration references, defaults, and global configuration
// inspection are not rewritten. Invalid namespace syntax or a nil engine // inspection are not rewritten. [Engine.ListNamespaces] and
// returns an error matching ErrInvalidConfig. // [Engine.ListCollections] remain global inventories. Invalid namespace syntax
// or a nil engine returns an error matching ErrInvalidConfig.
func (e *Engine) WithNamespaces(namespaces Namespaces) (*Engine, error) { func (e *Engine) WithNamespaces(namespaces Namespaces) (*Engine, error) {
if e == nil || e.internal == nil { if e == nil || e.internal == nil {
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig) return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)

View File

@@ -104,8 +104,9 @@ type ExecutionEvent struct {
RunID string RunID string
Time time.Time Time time.Time
PromptID string PromptID string
// PromptVersion is the selected definition's descriptive label. Each event // PromptVersion is the selected definition's optional descriptive label and
// owns its pointer; nil means absent while a non-nil empty string is explicit. // never participates in prompt selection. Each event owns its pointer; nil
// means absent while a non-nil empty string is explicit.
PromptVersion *string PromptVersion *string
ProfileID string ProfileID string
BackendID string BackendID string

View File

@@ -8,13 +8,16 @@ import (
) )
// RequirementInspectionRequest selects a prompt and supplies caller context // RequirementInspectionRequest selects a prompt and supplies caller context
// for requirement discovery. It requires no artifact bindings or credentials. // for requirement discovery. A namespace-scoped engine view qualifies
// slashless caller IDs; otherwise IDs select exact configured resources. It
// requires no artifact bindings or credentials.
type RequirementInspectionRequest struct { type RequirementInspectionRequest struct {
// PromptID is the exact, case-sensitive configured prompt ID. // PromptID is the exact, case-sensitive configured prompt ID, or a slashless
// caller ID qualified by a namespace-scoped engine view.
PromptID string PromptID string
// ProfileID selects the exact effective profile identity. If empty, the // ProfileID selects the exact effective profile identity, or a slashless
// prompt's default profile is used; the profile need not be ready for // caller ID qualified by a namespace-scoped view. If empty, the prompt's
// execution. // default profile is used; the profile need not be ready for execution.
ProfileID string ProfileID string
// Vars supplies string values for caller-variable lookups and simple // Vars supplies string values for caller-variable lookups and simple
// conditions. Presence is determined by exact map key, including an empty // conditions. Presence is determined by exact map key, including an empty
@@ -116,8 +119,9 @@ type RequirementIssue struct {
// prompt context. Input and variable entries are sorted by exact name. Issues // prompt context. Input and variable entries are sorted by exact name. Issues
// are deduplicated by code and associated names, then sorted by that tuple. // are deduplicated by code and associated names, then sorted by that tuple.
// Their descriptions and entry explanations are safe summaries, not // Their descriptions and entry explanations are safe summaries, not
// machine-readable details. PromptVersion is caller-owned: nil means no label // machine-readable details. PromptVersion is caller-owned descriptive metadata,
// was declared; a non-nil empty string is explicit. // not a selection key: nil means no label was declared; a non-nil empty string
// is explicit.
// //
// Complete describes the supported analysis's discovery coverage, not whether // Complete describes the supported analysis's discovery coverage, not whether
// requirements are supplied, templates will render, artifacts or schemas are // requirements are supplied, templates will render, artifacts or schemas are
@@ -129,8 +133,9 @@ type RequirementIssue struct {
type RequirementInspection struct { type RequirementInspection struct {
// PromptID is the selected exact prompt ID. // PromptID is the selected exact prompt ID.
PromptID string PromptID string
// PromptVersion is the selected definition's descriptive version label. Nil // PromptVersion is the selected definition's descriptive version label and
// means no label was declared; a non-nil empty string is an explicit label. // never participates in prompt selection. Nil means no label was declared; a
// non-nil empty string is an explicit label.
PromptVersion *string PromptVersion *string
// ProfileID is the selected profile identity; it does not indicate // ProfileID is the selected profile identity; it does not indicate
// execution readiness. // execution readiness.
@@ -149,12 +154,13 @@ type RequirementInspection struct {
} }
// InspectRequirements discovers inputs and caller variables for one selected // InspectRequirements discovers inputs and caller variables for one selected
// prompt before its input artifacts exist. It uses exact, case-sensitive // prompt before its input artifacts exist. It selects an exact, case-sensitive
// prompt selection and requires a profile ID either in the request or the // prompt ID; a namespace-scoped view qualifies slashless caller IDs before
// selected prompt's default. The selected profile establishes identity only; // lookup. A profile ID is required either in the request or the selected
// it need not be execution-ready. A normalized nonblank SessionID bypasses the // prompt's default. The selected profile establishes identity only; it need
// captured session template. Vars are copied before analysis, and returned // not be execution-ready. A normalized nonblank SessionID bypasses the captured
// slices and metadata pointers belong to the caller. // session template. Vars are copied before analysis, and returned slices and
// metadata pointers belong to the caller.
// //
// Discovery recognizes literal input names, direct caller-map keys, literal- // Discovery recognizes literal input names, direct caller-map keys, literal-
// key root-map lookups, simple caller-derived input names, and if/with // key root-map lookups, simple caller-derived input names, and if/with

View File

@@ -35,11 +35,13 @@ type SmokeTestRequest struct {
// selection otherwise needs a profile. A selected profile determines its own // selection otherwise needs a profile. A selected profile determines its own
// effective backend identity. // effective backend identity.
BackendID string BackendID string
// PromptID selects the prompt's default profile when ProfileID is empty. The // PromptID selects the prompt's default profile when ProfileID is empty. A
// prompt's messages, inputs, templates, and output contract are not executed. // namespace-scoped engine view qualifies a slashless caller ID. The prompt's
// messages, inputs, templates, and output contract are not executed.
PromptID string PromptID string
// ProfileID explicitly selects a profile and takes precedence over a prompt's // ProfileID explicitly selects a profile; a namespace-scoped view qualifies
// default profile and a backend's configured diagnostic default. // a slashless caller ID. It takes precedence over a prompt's default profile
// and a backend's configured diagnostic default.
ProfileID string ProfileID string
// Execution overrides applicable target settings using the same semantics as // Execution overrides applicable target settings using the same semantics as
// ordinary execution. HTTP probes do not require a model setting. // ordinary execution. HTTP probes do not require a model setting.
@@ -115,9 +117,10 @@ type SmokeTestTarget struct {
BackendID string BackendID string
// ProfileID is the selected profile, if any. // ProfileID is the selected profile, if any.
ProfileID string ProfileID string
// PromptID identifies the selected prompt; PromptVersion carries its // PromptID identifies the selected prompt; PromptVersion carries optional
// descriptive version label. Nil means absent while a non-nil empty string is // descriptive metadata and never participates in selection. Nil means absent
// explicit. The pointer belongs to this returned target. // while a non-nil empty string is explicit. The pointer belongs to this
// returned target.
PromptID string PromptID string
PromptVersion *string PromptVersion *string
// DefaultSourceBackendID identifies the backend whose configured default // DefaultSourceBackendID identifies the backend whose configured default
@@ -225,8 +228,10 @@ const (
// SmokeTest runs one built-in diagnostic against the engine's captured // SmokeTest runs one built-in diagnostic against the engine's captured
// configuration. // configuration.
// //
// Selection prefers an explicit ProfileID, then the profile selected by // On a namespace-scoped view, slashless caller-supplied prompt, profile, and
// PromptID, then a configured backend default profile when // backend IDs are qualified before selection; captured defaults and references
// remain unchanged. Selection prefers an explicit ProfileID, then the profile
// selected by PromptID, then a configured backend default profile when
// inference requires one. For backend-only probes, a selected profile supplies // inference requires one. For backend-only probes, a selected profile supplies
// its backend metadata; otherwise BackendID selects a backend directly without // its backend metadata; otherwise BackendID selects a backend directly without
// resolving its default inference profile. A selected profile determines its // resolving its default inference profile. A selected profile determines its

View File

@@ -85,9 +85,13 @@ const (
// own private execution snapshot for RunPrepared. Excessively deep or large // own private execution snapshot for RunPrepared. Excessively deep or large
// JSON-shaped values are rejected for safety. // JSON-shaped values are rejected for safety.
type RunRequest struct { type RunRequest struct {
// PromptID is the required non-empty prompt identifier. // PromptID is the required prompt identifier. A namespace-scoped engine view
// qualifies a slashless caller value; otherwise it selects the exact
// configured ID. Descriptive prompt-version labels do not participate in
// selection.
PromptID string PromptID string
// ProfileID selects an execution profile. When empty, the prompt's default // ProfileID selects an execution profile. A namespace-scoped engine view
// qualifies a slashless caller value. When empty, the prompt's default
// profile is used; if both are empty, the error matches ErrProfileRequired // profile is used; if both are empty, the error matches ErrProfileRequired
// and ErrInvalidRequest. // and ErrInvalidRequest.
ProfileID string ProfileID string
@@ -159,9 +163,10 @@ type RunRequest struct {
type PreparedRun struct { type PreparedRun struct {
// PromptID is the selected prompt identifier. // PromptID is the selected prompt identifier.
PromptID string `json:"prompt_id"` PromptID string `json:"prompt_id"`
// PromptVersion is the selected definition's descriptive version label. Nil // PromptVersion is the selected definition's descriptive version label and
// means no label was declared; a non-nil empty string is explicit. JSON omits // never participates in prompt selection. Nil means no label was declared; a
// nil and preserves a declared empty string. // non-nil empty string is explicit. JSON omits nil and preserves a declared
// empty string.
PromptVersion *string `json:"prompt_version,omitempty"` PromptVersion *string `json:"prompt_version,omitempty"`
// PromptHash is an opaque equality value for the selected definition. // PromptHash is an opaque equality value for the selected definition.
PromptHash string `json:"prompt_hash,omitempty"` PromptHash string `json:"prompt_hash,omitempty"`
@@ -219,9 +224,10 @@ type RunResult struct {
Validation ValidationResult `json:"validation"` Validation ValidationResult `json:"validation"`
// PromptID is the selected prompt identifier. // PromptID is the selected prompt identifier.
PromptID string `json:"prompt_id"` PromptID string `json:"prompt_id"`
// PromptVersion is the selected definition's descriptive version label. Nil // PromptVersion is the selected definition's descriptive version label and
// means no label was declared; a non-nil empty string is explicit. JSON omits // never participates in prompt selection. Nil means no label was declared; a
// nil and preserves a declared empty string. // non-nil empty string is explicit. JSON omits nil and preserves a declared
// empty string.
PromptVersion *string `json:"prompt_version,omitempty"` PromptVersion *string `json:"prompt_version,omitempty"`
// PromptHash is the same opaque definition equality value exposed by // PromptHash is the same opaque definition equality value exposed by
// PreparedRun. // PreparedRun.
@@ -404,10 +410,12 @@ type PromptInputDefinition struct {
// OutputContract is the normalized contract declared by the prompt definition, // OutputContract is the normalized contract declared by the prompt definition,
// rather than a request-level effective override. PromptHash is opaque. // rather than a request-level effective override. PromptHash is opaque.
type PromptInspection struct { type PromptInspection struct {
// PromptID is the normalized ID of the selected prompt definition. // PromptID is the exact selected prompt ID after any namespace-view
// qualification.
PromptID string PromptID string
// PromptVersion is the selected definition's descriptive version label. Nil // PromptVersion is the selected definition's descriptive version label and
// means no label was declared; a non-nil empty string is an explicit label. // never participates in definition selection. Nil means no label was
// declared; a non-nil empty string is an explicit label.
PromptVersion *string PromptVersion *string
// PromptHash is the opaque equality value for the selected definition. // PromptHash is the opaque equality value for the selected definition.
PromptHash string PromptHash string