Document resource inspection and source migrations

This commit is contained in:
2026-11-06 15:31:16 +00:00
parent ea31e71280
commit 19a0604874
8 changed files with 148 additions and 60 deletions

View File

@@ -45,6 +45,12 @@ boundary and constraints that framework work must preserve.
## Release Guidance
The [planned v0.20.0 release notes](docs/releases/v0.20.0.md) describe resource
inspection, typed prompt sources, and the profile null-fallback migration.
The [v0.19.0 release notes](docs/releases/v0.19.0.md) cover audit remediation
and compatibility changes to artifact ownership, programmatic sources, and schemas.
The [v0.18.0 release notes](docs/releases/v0.18.0.md) cover the default-on
OpenRouter backend and profiles, recorded configuration normalization, and
ConfigKit v1.1. The notes explain inventory changes and the bundle opt-out;

View File

@@ -94,7 +94,7 @@ engine, err := promptkit.NewEngine(promptkit.Config{
For a single highest-priority document, set `Sources.Main` to a
`*configkit.Input`; omit it for ordinary layered construction. A single file
can use `configkit.File` directly. `ProfileSource`, `BackendSource`, and raw
can use `configkit.File` directly. `PromptSource`, `ProfileSource`, `BackendSource`, and raw
`configkit.Mapping` supply programmatic definitions. Schema and runtime
collaborator options remain available. Construction validates the final
effective configuration and captures referenced prompt content; construct a
@@ -177,8 +177,12 @@ input := configkit.Input{Source: document}
// Add input to a later underlay, or set Sources.Main = &input.
```
`ProfileSource` and `BackendSource` are smaller typed conveniences when null
is not needed. Their provider maps use ConfigKit Mapping input forms: built-in
`PromptSource`, `ProfileSource`, and `BackendSource` are typed conveniences when
null is not needed. Prompt and backend helpers, like profiles, support sibling
inheritance via `Extends`; partial records can be completed by other layers.
For relative prompt `content_file` references, supply the ordinary ConfigKit
`Input.Filesystem` context for that source. The helpers do not read files or
validate final definitions. Profile and backend provider maps use ConfigKit Mapping input forms: built-in
scalars, `[]any`, and `map[string]any` recursively. Convert `json.Number` or
typed containers explicitly to an appropriate supported value, choosing numeric
precision for your application. Mapping captures supported values immediately;
@@ -264,9 +268,10 @@ is not necessarily safe to share. Inspection uses the engine's captured result
and does not reopen sources or resolve credentials. It retains effective values,
including recorded field normalization and queue defaulting, alongside source
provenance.
`InspectProfile` instead shows backend-completed execution settings for one profile, and `Prepare` or
`PreparedExecution.Details` shows request-specific rendered messages, inputs,
and validation resources. None of those views is a substitute for the others.
`InspectPrompt`, `InspectProfile`, and `InspectBackend` instead show individual
resolved resources without backend-to-profile execution completion or provenance.
`Prepare` or `PreparedExecution.Details` shows completed request-specific settings,
rendered messages, inputs, and validation resources. None substitutes for the others.
To review changes between two independently captured configurations, compare
their inspection views:
@@ -380,8 +385,10 @@ if err != nil {
return err
}
for _, input := range inspection.Inputs {
// Compare the declared input with application configuration.
if inspection.Inputs != nil {
for _, input := range *inspection.Inputs {
// Compare the declared input with application configuration.
}
}
```
@@ -707,10 +714,9 @@ composition rules.
### Inspect A Profile Before Prompt Work
Use [`Engine.InspectProfile`](../../engine.go) to validate one configured
profile without constructing a synthetic prompt or placeholder inputs. It
resolves the profile's effective target but does not prepare or execute a
prompt:
Use [`Engine.InspectProfile`](../../engine.go) to inspect a resolved profile
without constructing a synthetic prompt or placeholder inputs. It reports the
profile's own fields, not a backend-completed target:
```go
inspection, err := engine.InspectProfile(ctx, profileID)
@@ -718,24 +724,48 @@ if err != nil {
return err
}
target := inspection.EffectiveModelParams
if inspection.APIKeyRequired {
if inspection.APIKeyRequired != nil && *inspection.APIKeyRequired {
// Arrange a usable direct or configured environment credential.
}
if target.APIKeyEnv != "" {
if inspection.APIKeyEnv != nil {
// This is the configured environment lookup source, not its value.
}
```
Use this configuration-time boundary when only the profile and its target need
checking. Use `Prepare` when the application also needs prompt, input, schema,
or rendering work; use prepared execution when that work must remain tied to a
later execution. A reported `APIKeyEnv` identifies a configured source, while
`APIKeyRequired` is the explicit requirement; both may be present. The
Use [`InspectBackend`](../../engine.go) to inspect the referenced backend
separately. Its diagnostics are configured metadata, not live checks or derived
destinations; `ErrBackendNotFound` identifies an absent backend. References in
all three resource reports remain as authored. Use `Prepare` for completed
request settings and rendering, or prepared execution when that work must remain
tied to later execution. A reported `APIKeyEnv` identifies a configured source,
not its value; `APIKeyRequired` can also be present. The
[credential format reference](../formats.md#credentials) and the method's
[GoDoc](../../engine.go) own the exact precedence, timing, result, and error
contracts.
Resource inspection pointers represent optional fields: nil is absent, while a
non-nil pointer preserves zero, false, or an empty string. Pointer-to-collection
fields distinguish omission from an empty map or list. Results and nested mutable
values belong to the caller. Ordinary generic encoders need no per-field adapter:
```go
jsonBytes, err := json.Marshal(inspection)
if err != nil { return err }
yamlBytes, err := yaml.Marshal(inspection) // go.yaml.in/yaml/v4
if err != nil { return err }
_, _ = jsonBytes, yamlBytes
```
For migration, replace `ProfileInspection.EffectiveModelParams` accesses with
the optional resource fields, and use `Prepare` or `PreparedExecution.Details`
where backend completion and request overrides are needed. Prompt inspection's
`DefaultProfileID`, `Inputs`, nested input metadata, and output fields now use
optional pointers where presence matters; check for nil before dereferencing.
Consumers such as CommandKit can render the results directly instead of copying
each field into a parallel report. See the result types' [GoDoc](../../resource_inspection.go)
for keys and ownership; resource inspection does not replace `InspectConfiguration`
provenance, `InspectRequirements`, or concrete-request `ValidateRequest`.
### Set A Per-Run Session And Reasoning
Supply a direct session ID when one prompt should be correlated with a

View File

@@ -110,8 +110,8 @@ and static template syntax at construction. It does not reread configuration or
message files on ordinary runs; construct a new engine to observe edits.
Schema and request artifact reads still happen during preparation. Use
`InspectConfiguration` for an explicit effective-configuration or provenance
report, `InspectProfile` for backend-completed profile settings, and preparation
for request-specific rendered details. For identity discovery before inspection,
report, resource inspection for resolved prompt, profile, and backend fields,
and preparation for completed request-specific details. For identity discovery before inspection,
see the consumer guide's [resource and collection listing](consumers/pkg-promptkit.md#discover-available-resources-and-collections).
## Prompt Definitions
@@ -315,17 +315,33 @@ only a model or backend does not clear unrelated explicitly inherited fields.
| Profile field | Absent | Explicit value | Explicit null |
| --- | --- | --- | --- |
| `backend` | No backend | Exact backend ID; blank means none | No backend |
| `endpoint` | Selected backend endpoint | Valid nonblank URL; empty clears | Clear, without backend fallback |
| `endpoint` | Selected backend endpoint | Valid nonblank URL; empty clears | Selected backend endpoint |
| `model` | Unspecified | Nonblank model; empty clears | Unspecified |
| `temperature`, `top_p`, `max_tokens` | Unspecified | Valid value, including outbound zero | Suppress outbound control |
| `service_tier`, `reasoning_effort` | Unspecified | Normalized value; blank suppresses | Suppress outbound control |
| `timeout_seconds` | 600 seconds | Nonnegative; zero disables generation deadline | Reset to 600 seconds |
| `api_key_env` | Backend lookup name, if any | Trimmed name; blank disables | Disable backend lookup |
| `api_key_env` | Backend lookup name, if any | Trimmed name; blank disables | Backend lookup name, if any |
| `api_key_required` | False | Boolean, including false | False |
| `extra_params` | Backend defaults | Recursively overlay profile map on backend map | Suppress configured provider map |
| `extra_params` | Backend defaults | Recursively overlay profile map on backend map | Backend defaults |
An empty profile mapping does not clear backend map entries. After ConfigKit
composition and inheritance, a whole-map null and omission both permit backend
defaults. Nested maps merge recursively, while scalar and array values replace;
nulls within provider maps or arrays remain literal data.
When `api_key_required` is true and the profile source is absent or null,
execution suppresses the backend credential source; an explicitly configured
profile source remains in use.
For example, if the backend provides an endpoint, API-key environment name,
and provider map, a profile containing `endpoint: null`, `api_key_env: null`,
and `extra_params: null` now inherits those backend values after handoff (unless
the required-key rule suppresses the credential source). Earlier versions used
those nulls to suppress the corresponding fallback. Use `endpoint: ""` or
`api_key_env: ""` to clear those individual strings. There is no profile-level
whole-map suppression replacement; change the backend map through ordinary
ConfigKit composition when different provider defaults are needed. ConfigKit's
retained configuration and provenance continue to show the nulls.
An empty mapping does not clear inherited map entries; null clears the whole
map. Nested maps merge recursively, while scalar and array values replace.
Runtime nonempty `ExtraParams` overrides replace the entire configured map.
Request overrides otherwise follow the [public value GoDoc](../types.go).
For example, a runtime `extra_params["extends"]` key is ordinary provider

View File

@@ -11,15 +11,15 @@ contributor workflow and validation.
| Component | Implemented responsibility | References |
| --- | --- | --- |
| 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) |
| Root `promptkit` package | Provides the supported engine facade, ConfigKit source helpers, collection and resource mapping conveniences, injection options, public requests and results, resource and 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 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/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/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/configuration` | Loads root and namespaced resources through ConfigKit; validates final values, captures indexed resource views and source-relative prompt content, compiled templates, requirement metadata, identity inventories, backend and presence-aware execution profiles, and the read-only provenance 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/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 resource inspection and identity listing directly to the captured configuration rather than the runner. | [Engine assembly](../../internal/engine/engine.go), [internal sources](sources.md#typed-configuration-loading), [internal runner](runner.md) |
| `internal/generation` | Coordinates frozen built-in HTTP attempts and one-shot injected calls through active backend permits, including bounded status retries, cancellable backoff, ordinary attempt observations, and invocation-local evidence for diagnostics. | [Internal generation coordination](generation.md) |
| `internal/defaults` | Defines application-neutral framework constants and constructs the default execution target. It contains no CLI, server, or inbound HTTP limits. | [Framework defaults](../../internal/defaults/defaults.go) |
| `internal/filecatalog` | Provides deterministic YAML discovery and path helpers for operating-system filesystems and `fs.FS` sources. | [File catalog](../../internal/filecatalog/catalog.go) |

View File

@@ -45,12 +45,10 @@ captured when the engine was built.
Rendering uses those captured parses, cloning them per call to bind request
input helpers; it does not parse templates during execution.
`InspectPrompt` selects captured metadata directly from the repository. It
returns owned metadata without
rendering templates or touching profile, artifact, schema, renderer, validator,
admission, or model collaborators. The root
[`Engine.InspectPrompt`](../../engine.go) GoDoc owns the public operation's
exact contract.
Resource inspection bypasses the runner: the internal engine selects a captured
configuration resource, and the facade detaches its values for the caller.
Prompt resource inspection includes captured message text without rendering or
touching profile, artifact, schema, admission, or model collaborators.
`InspectRequirements` uses the same metadata selection to resolve the
request-profile/default identity, then obtains the captured requirement
@@ -64,17 +62,12 @@ operation's exact contract.
## Shared Profile Selection
The runner uses one profile-selection and target-resolution boundary for
ordinary preparation and exact profile inspection. Preparation first selects a
request profile or a prompt default; inspection begins with its required
explicit profile ID. Both use the captured, presence-aware target constructed
from the final effective profile and backend configuration. Request overrides
apply afterward; preparation checks endpoint and model completeness only after
those overrides. Inspection can report a partial profile without requiring a
runnable target. Neither path checks credential availability or performs prompt,
artifact, schema, rendering, admission, or model-client work. The root
[`Engine.InspectProfile`](../../engine.go) GoDoc owns the public operation's
exact contract.
The runner selects a request profile or a prompt default and uses its captured,
presence-aware target constructed from final profile and backend configuration.
Request overrides apply afterward; preparation checks endpoint and model
completeness only after those overrides. Resource profile inspection bypasses
this path and reports the profile before backend completion. Credential
availability is checked when execution preparation requires it.
## Smoke-Test Diagnostics

View File

@@ -11,8 +11,8 @@ source semantics. Internal packages are not consumer APIs.
## Typed Configuration Loading
`internal/configuration` is the single adapter from ConfigKit's final
effective configuration to execution-owned definitions. It performs one
layered load, captures effective presence (including explicit null), records
effective configuration to execution-owned definitions and resource views. It performs one
layered load, captures the needed effective presence, records
field-level normalization and derived defaults during resolution, and validates all effective
root and collection backend, profile, and prompt values. Replaced lower-layer
domain values are not separately validated. It indexes root resources under
@@ -94,13 +94,13 @@ presence, validation, sensitivity, and resource context; full IDs select
captured runtime indexes. Unchanged content-file fields retain their origins.
Backend-to-profile and request-time completion remain separate runtime work.
The runner selects full definitions from this index for preparation and uses
captured prompt metadata for `InspectPrompt` and `InspectRequirements`; the
internal requirement snapshot lookup uses the selected prompt ID alone.
These paths do not rescan configuration or reopen message files. `InspectPrompt`
returns declared metadata without rendering or resolving profile, input, or
schema resources, and its public shape and prompt hashes do not include the
captured presence state. Runtime rendering still checks request variables and
The runner selects full definitions from this index for preparation and retains
lightweight prompt metadata for `InspectRequirements`; the requirement snapshot
lookup uses the selected prompt ID alone. Separate configuration-owned resource
inspection projects the resolved record and captured messages without rendering
or resolving profile, input, or schema resources. These paths do not rescan
configuration or reopen message files. Presence metadata does not change the
opaque definition hash. Runtime rendering still checks request variables and
input helpers. The [prompt adapter tests](../../internal/configuration/prompts_test.go)
cover resource origins, context containment, capture, and selection.
@@ -149,10 +149,12 @@ ConfigKit resolves profile inheritance before the handoff. Within a collection,
`extends: {id: parent}` names a sibling local ID; it is not a cross-collection reference.
The configuration adapter validates final effective resource references and
field values, then captures backend definitions and profile target snapshots
with backend defaults and presence/suppression state. A profile can
remain partial until runtime overrides complete it. `InspectProfile` selects
that captured target without prompt, artifact, schema, credential lookup, or
provider work. Preparation applies runtime overrides and then checks target
with backend defaults and outbound-control presence. Null profile endpoint,
credential source, and whole provider map permit backend fallback after
composition, subject to the required-credential rule. A profile can remain
partial until runtime overrides complete it. Resource inspection selects indexed
resolved backend and profile records without execution completion or prompt,
artifact, schema, credential lookup, or provider work. Preparation applies runtime overrides and then checks target
completeness. Identity-only profile selection can identify a partial captured
profile without copying its target or requiring readiness. The
[target tests](../../internal/configuration/targets_test.go) cover effective

37
docs/releases/v0.20.0.md Normal file
View File

@@ -0,0 +1,37 @@
# Promptkit v0.20.0
This minor release adds generically renderable resource inspection and typed
prompt source construction. The Go consumer minimum remains 1.27.0 and
ConfigKit remains at v1.1.0.
## Compatibility And Migration
`InspectProfile` now returns the resolved profile resource instead of the
backend-completed `EffectiveModelParams`. Replace accesses to that field with
the optional profile fields; use `Prepare` or `PreparedExecution.Details` for
completed request settings. `InspectPrompt` now includes captured messages and
uses optional pointers for presence-sensitive fields, including default profile,
inputs, input metadata, and output settings. Check pointers before dereferencing.
All three resource reports support ordinary JSON and YAML rendering without
per-field adapters. See the [consumer guidance](../consumers/pkg-promptkit.md#inspect-a-profile-before-prompt-work).
After configuration composition and inheritance, profile null endpoint,
API-key source, and whole provider map now permit backend defaults during
execution as well as appearing absent in resource inspection. Use explicit
empty strings to clear endpoint or API-key source. There is no replacement for
profile-level suppression of an entire backend provider map; edit backend
defaults through composition instead. The required-key rule still applies.
See [defaults and overrides](../formats.md#defaults-and-overrides) for the
migration example and retained ConfigKit null provenance.
## Resource Inspection And Sources
`InspectBackend` reports the resolved backend and configured diagnostics without
contacting a provider or deriving diagnostic destinations. Prompt and profile
inspection likewise report selected resources independently of request readiness;
configuration provenance, requirement analysis, and preparation remain separate.
`PromptSource` adds typed programmatic prompt definitions, and `BackendConfig`
supports sibling inheritance. ConfigKit continues to own source composition,
snapshotting, and relative message-file contexts.
[COPYRIGHT](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/v0.20.0/COPYRIGHT) | [LICENSE](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/v0.20.0/LICENSE) | [ATTRIBUTION](https://forge.maximumdirect.net/base-layer/promptkit/src/tag/v0.20.0/docs/oss/attribution.md)

View File

@@ -527,6 +527,10 @@ authorization to edit another repository.
## Stage 11: Update Canonical Guidance And Migration Notes
**Completed:** Updated consumer, format, and internal guidance and prepared the
unpublished v0.20.0 note with licensing links. Changed local link targets and
whitespace were checked; the v0.20.0 tag was absent on the authoritative remote.
**Scope:** Documentation of the implemented APIs and intentional changes.
1. Update `docs/consumers/pkg-promptkit.md` with the three resource views,