From 19a0604874d359b97dd5445ba4ce8a1a2068a6f8 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Fri, 6 Nov 2026 15:31:16 +0000 Subject: [PATCH] Document resource inspection and source migrations --- README.md | 6 +++ docs/consumers/pkg-promptkit.md | 70 +++++++++++++++++++++++---------- docs/formats.md | 30 ++++++++++---- docs/internal/overview.md | 6 +-- docs/internal/runner.md | 27 +++++-------- docs/internal/sources.md | 28 +++++++------ docs/releases/v0.20.0.md | 37 +++++++++++++++++ docs/roadmap/implementation.md | 4 ++ 8 files changed, 148 insertions(+), 60 deletions(-) create mode 100644 docs/releases/v0.20.0.md diff --git a/README.md b/README.md index 0306e74..ba6663e 100644 --- a/README.md +++ b/README.md @@ -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; diff --git a/docs/consumers/pkg-promptkit.md b/docs/consumers/pkg-promptkit.md index 23cf1e1..ad9b749 100644 --- a/docs/consumers/pkg-promptkit.md +++ b/docs/consumers/pkg-promptkit.md @@ -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 diff --git a/docs/formats.md b/docs/formats.md index 7a39078..28af3aa 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -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 diff --git a/docs/internal/overview.md b/docs/internal/overview.md index 4a06d10..bbca30e 100644 --- a/docs/internal/overview.md +++ b/docs/internal/overview.md @@ -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) | diff --git a/docs/internal/runner.md b/docs/internal/runner.md index ddacb1f..370532b 100644 --- a/docs/internal/runner.md +++ b/docs/internal/runner.md @@ -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 diff --git a/docs/internal/sources.md b/docs/internal/sources.md index 3d7f525..c10d8bf 100644 --- a/docs/internal/sources.md +++ b/docs/internal/sources.md @@ -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 diff --git a/docs/releases/v0.20.0.md b/docs/releases/v0.20.0.md new file mode 100644 index 0000000..6c6e48f --- /dev/null +++ b/docs/releases/v0.20.0.md @@ -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) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 8877e02..4b7c685 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -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,