Files
promptkit/docs/roadmap/inspect-backend.md

415 lines
22 KiB
Markdown
Raw Normal View History

# Operator-Facing Resource Inspection And Configuration API Roadmap
2026-11-06 02:34:38 +00:00
## Purpose And Status
Help operators using CommandKit-based applications inspect the configured
prompt, profile, or backend selected by ID. CommandKit owns commands and report
presentation; Promptkit exposes the selected resource's resolved configuration.
The direction is accepted for planning; implementation has not begun. Selected
work includes fuller prompt inspection, profile inspection of the resolved
profile itself, a new `InspectBackend`, `BackendConfig.Extends`, and typed prompt
construction through `PromptConfig`/`PromptSource`. Execution-policy reporting
and prepared-request enhancements have been removed from this roadmap. The
decisions below record the accepted scope and representation approach.
## Resource-Inspection Boundary
“Fully resolved” means that ConfigKit has applied source composition and
inheritance to the selected resource. A child profile should show its resulting
keys and values, not an unresolved `extends` directive. It does not mean that
inspection assembles everything affecting execution.
| API | Resource shown |
| --- | --- |
| `InspectPrompt` | Resolved prompt definition, including captured imported message content. |
| `InspectProfile` | Resolved profile definition, before backend-to-profile execution completion. |
| Proposed `InspectBackend` | Resolved backend definition, including configured diagnostic metadata. |
For example, given:
```yaml
profiles:
- id: base
backend: openrouter
model: example-model
temperature: 0.5
- id: precise
extends: {id: base}
temperature: 0
```
The resource settings shown for `precise` are:
```yaml
id: precise
backend: openrouter
model: example-model
temperature: 0
```
ConfigKit inheritance contributes the parent's model and backend reference.
Promptkit's execution-time completion would obtain settings from that backend,
but those settings do not become fields of the inspected profile. The operator
can inspect the referenced backend separately. Likewise, prompt inspection
reports a default profile reference without incorporating that profile's values.
Use the captured, resolved configuration, including normalizations/defaults
already recorded in that configuration. Do not add framework execution defaults,
request overrides, credential values, or provider-derived defaults to fill
absent resource fields. For example, an absent profile timeout is not populated
from the framework generation timeout, while a queue default already recorded
in the resolved backend remains visible. See the
[format reference](../formats.md#source-headers-collections-and-resource-ids).
## Design Balance And Reporting
Provide useful resource information already captured or available with modest
projection. Reuse ConfigKit's resolved handoff and existing resource capture;
avoid another composition pass, execution resolver, parallel provenance system,
or duplicate retained graphs solely for inspection. These are proportionality
guidelines, not prohibitions on a small helper or type when it serves the API.
**Selected presentation:** Omit absent optional settings. Preserve explicit
values, including zero. Absence is not displayed as zero or `unspecified`.
Treat null like omission where they have the same meaning after ConfigKit
resolution. Preserve their distinction only where it changes resource behavior;
the mere presence of a null key is not enough to justify another public state.
The previous draft's rule to omit suppressed outbound controls belonged to an
execution report and does not define resource inspection. Accepted decision 4
selects typed results with this limited preservation of null semantics.
Inspection reports effective resource values rather than original YAML layout,
comments, or the history of each inherited field. `InspectConfiguration` remains
available for provenance. Existing opaque prompt identity/hash information can
remain alongside the resource view; it does not turn inspection into a source
round-trip API.
Retain existing captured-state, namespace, ownership, and credential-handling
contracts unless a change is deliberately selected. Mutable results should not
let a consumer change retained engine state; that does not require repeated
copies between private helpers or copying immutable strings. Ordinary resource
inspection needs no rendering, provider calls, or credential availability checks.
Templates and arbitrary provider settings remain application data whose
presentation and disclosure are controlled by the consuming application.
## Expanded Prompt Inspection
Expose description, ordered message templates with roles and cache-control
metadata, and the session-ID template, alongside the existing identity, hash,
default profile reference, input declarations, and output contract. Include
schema references and repair settings as part of the prompt definition.
Captured prompt definitions already retain the effective content of inline and
imported text/Markdown messages. Return that text without rendering or reopening
files. Original source layout and parsed-template objects are unnecessary.
The schema remains a reference; inspecting the prompt does not load it.
Keep prompt inspection independent of request readiness and default-profile
lookup. A captured prompt remains inspectable without a runnable default profile.
## Resolved Profile Inspection
This is a deliberate change to existing `InspectProfile` behavior. It currently
returns backend-completed `EffectiveModelParams`; the new resource boundary
requires the resolved profile's own fields instead.
Report fields supplied by the profile or inherited through ConfigKit, including
backend reference, endpoint/model where present, generation controls, credential
metadata, and provider parameters. Do not merge in backend provider defaults or
resolve an environment variable. Profiles may be partial, and their references
remain references. Distinguish omitted values, explicit zero, and meaningful
explicit null using the resolved resource's information, rather than inferring
presence from an execution target.
Execution target presence and prepared metadata describe a later resolution
stage and are not substitutes for profile configuration presence. Use the
existing configuration capture path to expose the needed information without
introducing a second configuration interpreter. Follow accepted decision 4 for
typed results and migration from `EffectiveModelParams`.
This roadmap changes no `Prepare`, `PreparedRun`, `PrepareExecution`, or
`PreparedExecution.Details` contract. Execution continues to apply backend
completion, framework defaults, and request overrides through its existing path.
## Backend Inspection
Proposed entry point:
2026-11-06 02:34:38 +00:00
```go
func (e *Engine) InspectBackend(
ctx context.Context,
backendID string,
) (*BackendInspection, error)
```
Expose the full backend identity and its resolved fields: base endpoint,
credential environment-variable name, provider defaults, concurrency/queue
settings, and configured `smoke_tests` metadata. Reuse suitable public nested
values where their semantics match; exact names and nesting follow decision 4.
Diagnostic metadata includes the configured authentication kind, profile
reference, and endpoint overrides after ConfigKit composition/inheritance.
An inherited endpoint override is a resolved configured value. An endpoint
computed later by a smoke-test adapter is not. Do not synthesize `/key` URLs,
reachability fallbacks, or a `smoke_tests` block that is absent from the resolved
backend. No shared diagnostic URL derivation work is required for this feature.
Inspecting a backend does not resolve its smoke-test default profile or contact
an endpoint. Report the configured reference even if that profile cannot be
selected. Capacity values describe configured policy, not current occupancy.
Follow the existing namespace-view selection rules: qualify slashless caller
IDs with the backend scope, pass qualified IDs through, and return the selected
full ID. Bundled and caller-defined resources use the same lookup rules.
Follow existing inspection conventions for invalid engines, invalid selections,
and cancellation. Missing-backend classification follows accepted decision 1.
## Consumer Integration And Compatibility
CommandKit can offer navigation between prompt, profile, and backend references
without combining their settings into the inspected resource. Stored references
retain their exact meaning; caller namespace defaults do not rewrite them.
A particular connected layout is a consumer choice, not a new Promptkit API.
Coordinate CommandKit adoption of the changed profile result and richer prompt
and backend views. In particular, migrate any formatter that currently expects
`EffectiveModelParams`. The profile semantic change must be documented as such,
not presented as merely adding more fields. Document the Go/serialization
migration for the typed result selected in decision 4 and follow the existing
release policy for compatibility changes.
Existing preparation APIs remain available for separate concrete-request uses;
this roadmap adds neither preview commands nor execution-policy report fields.
Transport timeouts, engine retry settings, caller deadlines, and injected-client
policy are outside the inspected resource unless they are actual fields of its
resolved definition. This is the scope of these APIs, not a pending engine-policy
feature decision.
## Typed Backend Inheritance
Add `Extends *string` to `BackendConfig`, matching `ProfileConfig.Extends`.
`BackendSource` encodes a non-nil value as `extends: {id: value}` and omits it
when nil. ConfigKit owns sibling inheritance and its diagnostics. The source
helper does not look up parents or populate inherited fields itself.
Keep existing root/collection identity, replacement, and null semantics. Raw
mappings remain available for generic controls outside the convenience helper.
See [resource inheritance](../formats.md#resource-inheritance) and the existing
[profile helper](../../profiles.go).
## Typed Prompt Sources
Add `PromptConfig` and `PromptSource` to complete the typed source-helper set
alongside `BackendConfig`/`BackendSource` and `ProfileConfig`/`ProfileSource`.
The proposed helper follows their calling convention:
```go
func PromptSource(label string, prompts []PromptConfig) configkit.Source
```
Cover prompt identity, sibling inheritance through `Extends`, default profile,
description, session template, inputs, messages with inline or file content and
cache controls, and output settings. Choose nested input types for configuration
semantics; reuse existing types where suitable without forcing execution or
inspection values into the source-input role.
Keep the helper a straightforward mapping constructor. Encode supplied fields
under a `prompts` list, then delegate to `configkit.Mapping`. Optional nil fields
mean omission; explicit values, including zero, false, and empty strings where
supported, must remain representable. Preserve nil-versus-empty collections
where that distinction matters to composition. Raw ConfigKit mappings remain
the escape hatch for explicit-null configuration operations and other advanced
composition controls outside the typed convenience surface.
The helper does not resolve inheritance, apply execution defaults, render
messages, read content files, or independently validate a prompt. Existing
ConfigKit composition and engine loading retain those responsibilities. Relative
content references use the ordinary input/source resource-context mechanism;
creating a typed source does not select a new filesystem root or file-loading
workflow. Reuse ConfigKit's source snapshot behavior rather than adding another
copier or recursive compatibility converter.
Keep all three source-helper families consistent in their scope and omission
conventions. They need not reproduce every generic configuration operation or
share a reflection-based encoding framework. Maintain the field mappings and
focused behavioral tests as the configuration model evolves.
## Related Work
Listing return-type consistency is a possible later cleanup, not required here.
Collections, schemas, and engine options do not need identical APIs merely for symmetry.
The [deferred fingerprint proposal](deferred.md#semantic-execution-target-fingerprints)
remains separate. Live capacity monitoring, provider health guarantees, and
source round-tripping are not selected deliverables.
## Decisions
All five decisions below are resolved. Numbering is retained for continuity with
the discussion; implementation is pending. The follow-up review of field-specific
null semantics in decision 4 does not select a configuration behavior change.
2026-11-06 02:34:38 +00:00
### 1. How Should An Unknown Backend Be Classified?
2026-11-06 02:34:38 +00:00
**Status:** Accepted; implementation pending.
**Decision:** Add public `ErrBackendNotFound` for an absent backend selected by
`InspectBackend`, following the existing prompt/profile sentinel pattern.
An ordinary missing-backend lookup should match `ErrBackendNotFound` through
`errors.Is` and should not also match `ErrInvalidRequest`. Reuse the registry's
existing internal missing-backend classification at the public boundary.
Invalid selections follow existing ID rules and match `ErrInvalidRequest`;
invalid engines match `ErrInvalidConfig`. Preserve context cancellation through
the existing inspection conventions. Invalid backend definitions remain an
engine-construction concern. Exact error wording is not a new contract.
Initially apply the new public classification to `InspectBackend`; do not
implicitly reclassify construction or smoke-test failures. CommandKit owns
operator wording and exit-status selection.
**Rationale:** This gives consumers a useful distinction with a small addition
consistent with prompt and profile inspection, without a new error hierarchy.
**Alternatives considered:** Using `ErrInvalidRequest` saves one public sentinel
but combines malformed selections and missing identities. A typed generic
resource-not-found error could carry resource kind and ID, but adds a broader
contract and integration questions for existing sentinels. Neither is selected;
the caller already knows the operation and requested ID.
### 2. Resource Inspection Does Not Include Execution-Policy Reporting
**Status:** Resolved; the former engine-policy proposal is removed from scope.
**Decision:** Inspect the selected resolved resource, not all settings that may
affect its execution. ConfigKit composition and inheritance are included;
backend-to-profile execution completion, framework execution defaults, request
overrides, and engine transport/retry reporting are not.
Remove the proposed engine-settings API, prepared-result policy fields, and
prepared-result presence enhancements from this roadmap. No decision about
where to place those additions remains necessary for resource inspection.
### 3. Should Typed Prompt Construction Be Added In This Round?
**Status:** Accepted; implementation pending.
**Decision:** Add `PromptConfig` and `PromptSource`, including inheritance,
following the thin mapping-constructor pattern described above. Retain the
backend/profile helpers and raw ConfigKit mapping support.
**Rationale:** API symmetry and convenient programmatic construction have value
as Promptkit approaches 1.0. The existing helpers are small explicit encoders;
a prompt helper adds nested input values and mappings, not a new authoring,
composition, or validation subsystem. That bounded maintenance cost is justified
by consistent discoverability and compiler assistance across all three resources.
**Alternatives considered:** Deferring prompt helpers would leave asymmetric Go
conveniences. Removing the existing typed helpers would simplify Promptkit's
surface but move string-keyed mapping construction to consumers and require
migration. Neither is selected. Full typed coverage of all ConfigKit operations
is unnecessary; raw mappings continue to serve those cases.
### 4. How Should Resolved Resource Results And Presence Be Represented?
**Status:** Accepted; implementation pending.
**Decision (Option A):** Use resource-oriented typed inspection results, reusing
suitable public nested values. Change `ProfileInspection` deliberately to report
the resolved profile rather than retaining a second execution-settings view for
compatibility. Apply the same resource semantics to prompt/backend additions.
Represent absent settings and explicit values, including zero, false, and empty
strings where valid. Preserve an omitted/null distinction only when it has a
meaningful effect after ConfigKit has finished resolution. Otherwise, treat null
as absent in the resource result. Clearing a parent's value during ConfigKit
inheritance is not, by itself, a reason to retain a third state afterward.
Use the smallest field-specific representation needed; a universal three-state
wrapper or generic resource framework is not selected. Execution-target presence
does not represent the uncompleted profile and must not substitute for it.
The current cases needing this distinction are profile `endpoint`, `api_key_env`,
and whole-map `extra_params`: they control whether later backend completion may
provide a value. Arbitrary nulls inside provider data remain provider data.
The [format reference](../formats.md#defaults-and-overrides) owns those semantics.
Their continuing value is a separate follow-up discussion; accepting typed
inspection does not endorse every existing null rule as permanently necessary
or authorize changing configuration behavior in this work.
**Rationale:** Typed results provide discoverable Go fields without making
consumers interpret a generic configuration mapping. Limiting additional
presence handling to meaningful cases avoids carrying source syntax and
inheritance history into every field. Existing implementation machinery is not
itself justification for a public distinction.
**Alternative considered:** A caller-owned resource mapping naturally represents
missing keys and null and can reduce per-field projection work, but sacrifices
typed discoverability and introduces a broader mapping-value contract. It is not
selected as the primary resource-inspection result; `InspectConfiguration`
remains available for explicit configuration/provenance inspection.
Document migration for existing `EffectiveModelParams` consumers and any
serialization changes with the final Go types. CommandKit owns report formatting;
new JSON contracts or custom serializers are not automatically required. Do not
leak internal package types or mutable captured state.
### 5. Backend Diagnostics Show Configured Values, Not Derived Destinations
**Status:** Resolved by the resource-inspection boundary.
**Decision:** Return diagnostic settings present in the resolved backend,
including inherited endpoint overrides. Leave omitted endpoint settings absent;
deriving a default destination belongs to diagnostic execution. The earlier
proposal to expose both declared and computed destinations is removed. This
avoids an additional representation and provider-specific derivation machinery
in resource inspection.
## Implementation And Verification
1. Define the typed results and migration selected in decision 4. Source-input
helper types and inspection results have distinct purposes; select their
shapes accordingly, with additional null handling only where meaningful.
2. Expose expanded prompt content and resolved profile fields through existing
capture/lookup paths, before execution completion. Preserve configured
presence/null distinctions only where meaningful, without another composition
pass.
3. Add backend inspection and the accepted public missing-backend error,
returning configured diagnostic metadata without endpoint derivation.
4. Add typed backend inheritance and the prompt source/helper types, delegating
both to the ordinary ConfigKit mapping and loading path.
5. Update GoDoc, consumer/internal guidance, and release notes for the selected
behavior and profile compatibility change. Coordinate CommandKit reporting.
Use focused offline tests for actual boundary risks:
- Child resources show the resolved inherited fields and overrides, not an
unresolved `extends` directive; explicit zero survives and absent fields
remain distinguishable from configured null where meaningful. Equivalent
omitted/null settings use the same absent representation; provider-data nulls
retain their literal meaning.
- Profile inspection excludes settings supplied only by a referenced backend,
framework execution defaults, or a request. Existing execution still applies
those settings through its ordinary resolution path.
- Prompt inspection exposes captured inline/imported content, metadata, and
order without rendering or adding related-resource lookup dependencies.
- Backend inspection reports configured/inherited diagnostic overrides while
leaving omitted overrides absent. It does not require diagnostic readiness.
- Resource selection, error classification, and mutable-result ownership follow
the selected contract; reuse existing namespace and ownership coverage.
- Typed backend and prompt inheritance work through real ConfigKit composition.
Prompt sources preserve nested message/input/output settings, omission and
explicit values, ordering, and source snapshot behavior. Include a representative
relative content-file case using ordinary source context. Reuse generic loading,
validation, and inheritance coverage rather than duplicating it for each helper.
CommandKit owns presentation tests for the migrated resource view. Follow the
[testing policy](../policy/testing.md), combine cases where useful, and reuse
existing coverage. No new benchmark threshold or release gate is selected.
Completion means operators can inspect the resolved selected prompt, profile,
or backend accurately without assembling execution settings or navigating raw
configuration paths. All three resource kinds have typed source helpers,
including inheritance support, and consumers have migration guidance for changed
profile inspection.
No engine-policy or prepared-request additions are part of completion.