Select typed inspection with meaningful null distinctions

This commit is contained in:
2026-11-06 12:43:56 +00:00
parent 363920deb2
commit 3951dcf1f3

View File

@@ -10,7 +10,8 @@ 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. Decisions below record the accepted boundary and remaining choices.
and prepared-request enhancements have been removed from this roadmap. The
decisions below record the accepted scope and representation approach.
## Resource-Inspection Boundary
@@ -71,11 +72,12 @@ 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`.
An explicit null retained in the resolved resource is a configured value, not
an absent key; preserve that distinction where it affects resource semantics.
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. Representation of
presence/null in public results is open decision 4.
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
@@ -123,8 +125,8 @@ 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. The precise result shape and
migration from `EffectiveModelParams` are open decision 4.
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
@@ -173,8 +175,9 @@ 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. Select the Go/serialization migration
in decision 4 and follow the existing release policy for compatibility changes.
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.
@@ -242,8 +245,9 @@ source round-tripping are not selected deliverables.
## Decisions
Decisions 1, 2, 3, and 5 are accepted. Only decision 4 remains open. Numbering is
retained for continuity with the discussion; implementation is pending.
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.
### 1. How Should An Unknown Backend Be Classified?
@@ -308,29 +312,46 @@ is unnecessary; raw mappings continue to serve those cases.
### 4. How Should Resolved Resource Results And Presence Be Represented?
The chosen meaning of inspection is settled; the public Go shape and migration
from the existing backend-completed profile result are not.
**Status:** Accepted; implementation pending.
**Recommendation:** Use a resource-oriented typed profile result, reusing suitable
public nested values and representing absent/explicit-zero/explicit-null values
where needed. Prefer a deliberate, documented change to `ProfileInspection` over
retaining a second execution-settings view just for compatibility. Choose the
smallest presence representation supported by captured configuration; do not
reuse `ExecutionTargetPresence` as if it represented the uncompleted profile.
Apply the same resource semantics to prompt/backend result additions without
requiring a generic resource framework.
**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.
**Alternative:** Expose resolved resource fields as a caller-owned mapping,
possibly alongside typed identity and prompt metadata. That naturally represents
missing keys and null and can reduce per-field projection work, but gives up Go
field discoverability and requires careful definition of the mapping's values
and compatibility. Compare that cost with the typed representation rather than
assuming another complete family of public configuration types is necessary.
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.
Decide the migration for existing `EffectiveModelParams` consumers and any
serialization changes explicitly. CommandKit can own its report formatting;
new JSON contracts or custom serializers are not automatically required. Neither
option authorizes leaking internal package types or mutable captured state.
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
@@ -345,12 +366,13 @@ in resource inspection.
## Implementation And Verification
1. Resolve result representation/migration in decision 4. Source-input helper
types and inspection results have distinct purposes; select their shapes
accordingly.
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 without another composition pass.
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
@@ -362,7 +384,9 @@ 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.
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.