620 lines
35 KiB
Markdown
620 lines
35 KiB
Markdown
# Resource Inspection And Typed Sources Implementation Plan
|
|
|
|
## Purpose And Sprint Model
|
|
|
|
Implement the accepted [resource inspection roadmap](inspect-backend.md). That
|
|
document owns intent, scope, and product decisions; this plan owns the concrete
|
|
steps and representation choices needed to deliver them.
|
|
|
|
At baseline `951739e`, ConfigKit v1.1.0 composed and resolved definitions once.
|
|
Promptkit captured executable prompts and backend-completed profile targets.
|
|
`InspectPrompt` exposed limited metadata; `InspectProfile` exposed an
|
|
execution target. There was no `InspectBackend` or typed `PromptSource`, and
|
|
`BackendConfig` lacked `Extends`. Existing inspection values did not have the
|
|
selected generic JSON/YAML contract.
|
|
|
|
Each numbered stage is intended for one Luna implementation prompt, in order.
|
|
This is one end-to-end sprint: intermediate stages may fail to compile or leave
|
|
callers unmigrated. Do not build compatibility shims, optional capability probes,
|
|
dual public inspection modes, or temporary representations just to keep each
|
|
stage green. Run focused checks as their affected paths become buildable;
|
|
record deferred checks and resolve them before the final stage. There are no
|
|
intermediate human-review, publication, or downstream-release gates.
|
|
|
|
Follow [agent](../policy/agents.md), [architecture](../policy/architecture.md),
|
|
[testing](../policy/testing.md), and [documentation](../policy/documentation.md)
|
|
policies and the [configuration boundary ADR](../adr/0001-configuration-boundary.md).
|
|
Use the [development guide](../development.md) for toolchain selection and local
|
|
commits. Commit completed nonempty units and record stage completion here,
|
|
including checks run or deferred. Intermediate commits need not be releasable.
|
|
|
|
## Selected Implementation Decisions
|
|
|
|
### Resource Boundary And Internal Flow
|
|
|
|
All three public inspection operations return the selected resolved resource,
|
|
before execution completion. References remain references. Imported message
|
|
text comes from the already materialized prompt, not another file read.
|
|
|
|
Use a narrow, private resource-inspection interface on `internal/engine.Engine`,
|
|
implemented by the configuration snapshot, alongside its existing inspection
|
|
and listing collaborators. Its methods accept a context and exact full ID and
|
|
return configuration-owned internal resource views. The engine qualifies
|
|
caller IDs with the appropriate namespace and delegates. The root facade checks
|
|
engine validity, maps errors, and projects detached public values.
|
|
|
|
Keep configuration resource views under `internal/configuration`; they contain
|
|
no ConfigKit types in their engine-facing fields. Do not add these operations
|
|
to execution-profile, generation, capacity, or transport interfaces. Remove the
|
|
now-unused runner `InspectPrompt` and `InspectProfile` entry points when wiring
|
|
is switched. Retain execution selection helpers used by preparation and smoke
|
|
tests.
|
|
|
|
Requirement discovery still needs only the small existing prompt metadata
|
|
lookup and requirement snapshot. Keep `promptdef.Repository.GetPromptInspection`
|
|
and its narrow `domain.PromptInspection` for that purpose, with comments making
|
|
the distinction clear. Do not expand that internal value with message bodies.
|
|
The new configuration resource view is distinct from this lightweight execution
|
|
metadata. This avoids changing `InspectRequirements` into a full-resource copy.
|
|
|
|
Index resolved profile and backend configuration records by full ID once during
|
|
capture, reusing the already built indexed maps or references into the retained
|
|
result. Do not build full parallel configuration trees or query ConfigKit's
|
|
provenance during ordinary inspection. Prompt entries already retain captured
|
|
messages, templates, and hashes; use that capture and the selected prompt's
|
|
resolved values. Small presence metadata is appropriate where decoding has
|
|
already collapsed omission into a scalar default.
|
|
|
|
Internal views may borrow immutable captured values. Detach mutable data at the
|
|
public projection boundary, using existing trusted copy helpers for accepted
|
|
provider maps. Do not revalidate provider values merely to copy them. This is
|
|
an ownership strategy, not a new public allocation or complexity guarantee.
|
|
|
|
### Public Result Shapes
|
|
|
|
Keep the existing method signatures for prompt/profile inspection. Add:
|
|
|
|
```go
|
|
func (e *Engine) InspectBackend(ctx context.Context, backendID string) (*BackendInspection, error)
|
|
```
|
|
|
|
Declare the result types in `resource_inspection.go` at the module root. Move
|
|
the existing public `PromptInspection` and `ProfileInspection` declarations
|
|
there rather than leaving duplicate definitions. These are facade values, not
|
|
aliases of private types. Keep execution and extension type shapes unchanged.
|
|
|
|
The tables below specify Go fields, types, and serialized keys. Apply both
|
|
`json` and `yaml` tags with the same key. Required fields have no `omitempty`;
|
|
all pointer fields use `omitempty` and nil means absent. A non-nil pointer to
|
|
zero, false, an empty string, or an empty collection remains present.
|
|
|
|
| Result | Go fields and types | Serialized keys |
|
|
| --- | --- | --- |
|
|
| `ProfileInspection` | `ProfileID string` | `id` |
|
|
| | `Backend, Endpoint, Model *string` | `backend`, `endpoint`, `model` |
|
|
| | `Temperature, TopP *float64` | `temperature`, `top_p` |
|
|
| | `MaxTokens, TimeoutSeconds *int` | `max_tokens`, `timeout_seconds` |
|
|
| | `ServiceTier, ReasoningEffort *string` | `service_tier`, `reasoning_effort` |
|
|
| | `APIKeyEnv *string`, `APIKeyRequired *bool` | `api_key_env`, `api_key_required` |
|
|
| | `ExtraParams *map[string]any` | `extra_params` |
|
|
| `BackendInspection` | `BackendID string`, `Endpoint string` | `id`, `endpoint` |
|
|
| | `APIKeyEnv *string` | `api_key_env` |
|
|
| | `ConcurrencyLimit, QueueCapacity *int` | `concurrency_limit`, `queue_capacity` |
|
|
| | `ExtraParams *map[string]any` | `extra_params` |
|
|
| | `SmokeTests *BackendSmokeTestConfig` | `smoke_tests` |
|
|
| `PromptInspection` | `PromptID string`, `PromptHash string` | `id`, `prompt_hash` |
|
|
| | `DefaultProfileID, Description, SessionID *string` | `default_profile`, `description`, `session_id` |
|
|
| | `Inputs *[]PromptInputInspection` | `inputs` |
|
|
| | `Messages []PromptMessageInspection` | `messages` |
|
|
| | `OutputContract PromptOutputInspection` | `output` |
|
|
|
|
Remove `ProfileInspection.EffectiveModelParams`; do not retain a compatibility
|
|
copy of backend-completed settings. `APIKeyRequired` becomes an optional
|
|
profile resource field. Retain the familiar prompt field names `Inputs`,
|
|
`DefaultProfileID`, and `OutputContract`, but deliberately change their types
|
|
where needed for presence.
|
|
|
|
Nested prompt values are:
|
|
|
|
| Type | Go fields and types | Serialized keys |
|
|
| --- | --- | --- |
|
|
| `PromptInputInspection` | `Name string`, `Required *bool`, `ContentType, Description *string` | `name`, `required`, `content_type`, `description` |
|
|
| `PromptMessageInspection` | `Role string`, `Content string`, `CacheControl *PromptCacheControlInspection` | `role`, `content`, `cache_control` |
|
|
| `PromptCacheControlInspection` | `Type CacheControlType`, `TTL *string` | `type`, `ttl` |
|
|
| `PromptOutputInspection` | `Format OutputFormat`, `ValidationMode ValidationMode`, `SchemaPath *string`, `RepairAttempts *int` | `format`, `validation_mode`, `schema_path`, `repair_attempts` |
|
|
|
|
Required strings and enum values in these nested types are always encoded.
|
|
Imported and inline message bodies both use `content`; do not report a
|
|
`content_file` field or parsed template. Content is not rendered. A supplied
|
|
empty cache TTL stays present, unlike the existing execution cache-control
|
|
value's omission behavior. Keep `PromptInputDefinition`, `OutputContract`, and
|
|
execution `CacheControl` unchanged for their existing purposes.
|
|
|
|
Reuse `BackendSmokeTestConfig`, `ReachabilityProbeConfig`, and
|
|
`AuthenticationProbeConfig` for backend diagnostic metadata: their pointer
|
|
fields already fit the selected semantics. Add JSON/YAML tags to their fields
|
|
(`default_profile`, `reachability`, `authentication`, `endpoint`, `kind`), all
|
|
with `omitempty`. Preserve a configured empty reachability object as `{}`;
|
|
do not fill an omitted endpoint or invent a diagnostics block. This does not
|
|
make `BackendConfig` itself a serialization contract.
|
|
|
|
The supported generic encoding paths are `encoding/json` and the existing
|
|
`go.yaml.in/yaml/v4` dependency. Ordinary `Marshal`/`Encoder` calls must suffice.
|
|
Pointer-to-collection fields avoid needing public presence flags or custom
|
|
serializers to distinguish omitted collections from explicit `{}`/`[]`. Do not
|
|
add deserialization, source round-trip, output-order, or numeric precision
|
|
guarantees. Inspect values rather than inferring source syntax from zero values.
|
|
|
|
### Presence And Null Interpretation
|
|
|
|
Use resolved typed pointers and nil-versus-empty collections where they retain
|
|
presence. Capture only additional information needed for scalar fields such as
|
|
input `required` and output `repair_attempts` before they become execution
|
|
defaults. Inherited values count as present. For nullable resource fields,
|
|
resolved null and omission both produce nil in resource reports. Literal nulls
|
|
inside provider maps/arrays remain untouched.
|
|
|
|
Keep existing normalization and derived defaults recorded during the ConfigKit
|
|
resolution callback. In particular, positive backend concurrency with no queue
|
|
setting yields the already recorded queue default in inspection. Do not invent
|
|
an explicit zero concurrency value when the resolved field is absent, or add
|
|
the framework profile timeout merely because execution uses it.
|
|
|
|
Simplify `captureExecutionProfile` to use non-nil configured values rather than
|
|
profile-specific absent/null state. Endpoint, credential source, and whole-map
|
|
null now permit backend fallback. When `api_key_required` is true and the
|
|
profile's `APIKeyEnv` pointer is nil, suppress the backend credential source
|
|
just as for omission. An explicit empty endpoint or API-key source still clears
|
|
that value. A non-nil provider map still overlays backend values, including
|
|
an explicitly empty map that does not clear defaults. Nested provider nulls
|
|
remain literal data.
|
|
|
|
Remove the profile-only `state.profiles` presence map, `profileFields`, and
|
|
capture helpers made unused by this change. Retain helpers needed by other
|
|
metadata or validation; do not purge presence/null handling generically.
|
|
Preserve execution `ExecutionTargetPresence`, because provider control omission
|
|
and explicit zero still matter at dispatch. Do not change required-field or
|
|
non-nullable-field validation. ConfigKit's retained result and provenance are
|
|
not rewritten to erase nulls.
|
|
|
|
### Typed Prompt Source Shapes
|
|
|
|
Add `BackendConfig.Extends *string` and encode it exactly like the profile helper.
|
|
Add a root `prompts.go` containing these source-input types and helper:
|
|
|
|
```go
|
|
type PromptConfig struct {
|
|
ID string
|
|
Extends, DefaultProfile, Description, SessionID *string
|
|
Inputs []PromptInputConfig
|
|
Messages []PromptMessageConfig
|
|
Output *PromptOutputConfig
|
|
}
|
|
|
|
type PromptInputConfig struct {
|
|
Name string
|
|
Required *bool
|
|
ContentType, Description *string
|
|
}
|
|
|
|
type PromptMessageConfig struct {
|
|
Role, Content, ContentFile *string
|
|
CacheControl *PromptCacheControlConfig
|
|
}
|
|
|
|
type PromptCacheControlConfig struct {
|
|
Type, TTL *string
|
|
}
|
|
|
|
type PromptOutputConfig struct {
|
|
Format, ValidationMode, SchemaPath *string
|
|
RepairAttempts *int
|
|
}
|
|
|
|
func PromptSource(label string, prompts []PromptConfig) configkit.Source
|
|
```
|
|
|
|
These types are mapping-constructor inputs, not serialized result types. Match
|
|
`BackendSource`/`ProfileSource`: always write IDs/names, dereference supplied
|
|
pointers, omit nil optional fields, preserve non-nil empty slices/objects, and
|
|
return `configkit.Mapping(label, map[string]any{"prompts": records})`. Encode
|
|
`Extends` as `extends: {id: value}`. A nil top-level prompt slice supplies an
|
|
empty `prompts` sequence, matching the other source helpers.
|
|
|
|
Do not require a complete source record in the helper: higher layers or sibling
|
|
inheritance may complete it. Engine loading owns final validation, including
|
|
invalid content/content-file combinations. Raw mappings retain explicit-null
|
|
and generic ConfigKit operations. Do not add a Promptkit-specific content root,
|
|
filesystem adapter, recursive input converter, or inheritance resolver.
|
|
|
|
## Stage 1: Declare The Resource Result Contract
|
|
|
|
**Completed:** Public result fields and JSON/YAML tags reviewed against the
|
|
tables; compilation and encoding checks are deferred until the corresponding
|
|
projection and consumer migrations are complete.
|
|
|
|
**Scope:** Public inspection values and their nested representation only.
|
|
|
|
1. Read `types.go`, `backends.go`, and the current inspection GoDoc in `engine.go`.
|
|
Create the public result types and tags specified above. Move only the two
|
|
existing inspection declarations; leave execution types alone.
|
|
2. Add tags to the reused backend diagnostic types. Document optional pointer
|
|
and collection semantics, caller ownership, captured content, references,
|
|
credential metadata, and the resource/execution distinction.
|
|
3. Remove outdated claims that these inspection results have no serialization
|
|
contract. Do not remove those claims from unrelated types.
|
|
|
|
**Check:** Review every field against the tables, particularly pointer maps,
|
|
input `required`, cache TTL, and output `repair_attempts`. Compilation of old
|
|
converters and callers may wait for later stages; do not add transitional fields.
|
|
|
|
## Stage 2: Simplify Execution's Post-Handoff Null Semantics
|
|
|
|
**Completed:** Focused configuration tests pass with the locally selected Go
|
|
toolchain. Public resource and retained-provenance assertions for inherited nulls
|
|
remain scheduled with the inspection wiring and isolation checks.
|
|
|
|
**Scope:** Profile capture and its targeted configuration tests.
|
|
|
|
1. In `internal/configuration/targets.go`, implement the pointer-based behavior
|
|
above. Continue applying backend defaults once, then the explicit profile
|
|
values, then ordinary request-time overrides through the existing path.
|
|
2. In `load.go`, remove only the now-unused profile tri-state capture machinery.
|
|
Preserve final effective validation and prompt metadata capture.
|
|
3. Update `targets_test.go` and relevant `load_test.go`/`interpretation_test.go`
|
|
cases. Compare null and omission for endpoint, API-key source, and whole
|
|
provider map; retain explicit-empty-string clearing, empty-map overlay,
|
|
nested provider nulls, and `api_key_required` behavior with both absent/null
|
|
and explicit profile sources.
|
|
4. Include real ConfigKit inheritance where a child's null displaces a parent's
|
|
endpoint/provider map: the inspected resource is unset and execution uses
|
|
the selected backend, not the displaced parent. Preserve the null in the
|
|
retained configuration inspection. Inspection assertions may be completed
|
|
after resource wiring exists.
|
|
|
|
**Check:** Run the focused adapter tests when buildable. Retain outbound-control
|
|
presence and timeout behavior; removing configuration null distinctions must
|
|
not collapse runtime explicit zero or broaden accepted configuration shapes.
|
|
|
|
## Stage 3: Project Resolved Backend And Profile Resources
|
|
|
|
**Completed:** Exact-ID resource lookups reuse captured resolved indexes; focused
|
|
configuration tests cover partial inheritance, explicit values, backend defaults,
|
|
derived queue capacity, diagnostics, missing IDs, and cancellation.
|
|
|
|
**Scope:** Configuration-owned views and exact-ID resource lookup.
|
|
|
|
1. Add private-adapter result structs in `internal/configuration`, with fields
|
|
corresponding to the public profile/backend tables. Keep ConfigKit record
|
|
types and paths inside the adapter, and do not alias public root types.
|
|
2. Reuse the indexed resolved records built during `buildExecutionProfiles`
|
|
instead of discarding and recomputing those indexes for each inspection.
|
|
Values may reference the immutable retained config; avoid additional deep
|
|
retained copies of provider maps. Keep the execution registry/targets for
|
|
their current execution and smoke responsibilities.
|
|
3. Add adapter `InspectProfile(ctx, id)` and `InspectBackend(ctx, id)` lookups.
|
|
Build selected-resource views from the normalized resolved records, never
|
|
from `ExecutionProfile.ResolvedTarget` or the capacity manager. Use existing
|
|
internal not-found sentinels for absent IDs and preserve cancellation.
|
|
4. Include backend diagnostics only where configured after composition. Return
|
|
configured endpoint overrides, including inherited ones, and no derived URLs.
|
|
A missing diagnostic default profile does not prevent backend inspection.
|
|
5. Add focused adapter coverage using real ConfigKit loading: an inherited
|
|
partial profile, explicit zero/empty settings, backend defaults excluded
|
|
from that profile, and backend queue derivation and diagnostic metadata.
|
|
|
|
**Check:** Verify resource fields against the retained resolved config and
|
|
execution fields separately against the backend-completed target. Do not turn
|
|
backend/profile references into nested reports or require execution readiness.
|
|
|
|
## Stage 4: Capture Complete Prompt Resource Information
|
|
|
|
**Completed:** Captured prompt resources retain inherited scalar presence and
|
|
materialized message text independently of requirement metadata. Focused
|
|
configuration tests pass, including inherited file content and explicit values.
|
|
|
|
**Scope:** Prompt presence and resource projection, without changing execution
|
|
or requirement-discovery representations.
|
|
|
|
1. Extend the existing prompt metadata capture just enough to retain omission
|
|
versus explicit false for each input's `required`, and omission versus
|
|
explicit zero for `output.repair_attempts`. Use ConfigKit's effective entry
|
|
information during the existing callback, including inherited presence.
|
|
Keep non-nullable-field rejection intact; do not switch those scalars to
|
|
nullable fields as a shortcut.
|
|
2. Retain or reference the selected resolved prompt record for optional strings,
|
|
inputs-list presence, schema-path presence, and per-message cache TTL
|
|
presence. Do not create another copy of the whole configuration tree.
|
|
3. Add adapter `InspectPrompt(ctx, id)` returning its resource view. Use
|
|
captured `promptEntry.definition` message text/order and existing hash, plus
|
|
the resolved resource's presence. Do not reopen message files, render
|
|
templates, or load the referenced schema/default profile.
|
|
4. Leave `GetPromptInspection` and `domain.PromptInspection` lightweight for
|
|
`InspectRequirements`; keep requirement metadata, compiled templates, and
|
|
opaque definition hashing behavior independent of the expanded resource DTO.
|
|
5. Extend prompt adapter tests for inherited/imported captured content,
|
|
optional metadata, empty inline content, cache TTL absence versus empty,
|
|
and input/output scalar presence. Reuse existing content-origin fixtures.
|
|
|
|
**Check:** Inspect a prompt with an unresolved template variable and an absent
|
|
default profile/schema file successfully. Schema and template syntax validation
|
|
at construction remain as before. A later content-file change does not alter
|
|
the resource report or trigger a second read.
|
|
|
|
## Stage 5: Wire Resource Inspection Through The Engine And Facade
|
|
|
|
**Completed:** Captured resource views are wired through namespace selection
|
|
and detached public projections. An isolated assembled public-API test passes;
|
|
existing consumers and examples are migrated in the next stage.
|
|
|
|
**Scope:** Selection, public conversion, backend entry point, and errors.
|
|
|
|
1. Add the three-method resource-inspection interface and captured collaborator
|
|
to `internal/engine.Engine`; initialize it from the configuration snapshot
|
|
and share it naturally through `WithNamespaces`.
|
|
2. Route internal prompt/profile inspection through this collaborator instead
|
|
of the runner, and add backend inspection. Reuse `qualifyResourceID` with
|
|
each kind's namespace. Do not qualify references stored inside definitions.
|
|
3. Replace root inspection conversion with explicit projections of the new
|
|
configuration views. Copy pointer scalars and mutable maps/slices/nested
|
|
diagnostics into caller-owned values; reuse immutable strings. Use trusted
|
|
detachment for accepted nested provider values, not a serialization round
|
|
trip or a new JSON compatibility conversion.
|
|
4. Add public `ErrBackendNotFound` and `Engine.InspectBackend`. Scope the mapping
|
|
of the registry's internal not-found sentinel to this new operation; do not
|
|
globally reclassify construction, smoke, or generation errors. Follow the
|
|
existing nil/uninitialized-engine guards and invalid-ID conventions.
|
|
Preserve cancellation causes without inventing a public backend-load category.
|
|
5. Update exact method/type GoDoc, including `Engine`'s concurrent-operation
|
|
list. All three calls return no partial result on error and expose neither
|
|
credential values nor runtime occupancy.
|
|
|
|
**Check:** A small assembled public-API test for each method builds. Missing
|
|
backend matches `ErrBackendNotFound` and not `ErrInvalidRequest`; malformed IDs
|
|
match `ErrInvalidRequest`, invalid engines match `ErrInvalidConfig`, and
|
|
cancellation remains detectable through `errors.Is`.
|
|
|
|
## Stage 6: Retire Superseded Inspection Paths And Migrate Existing Tests
|
|
|
|
**Completed:** Removed superseded runner inspection wrappers, migrated public
|
|
consumers and the preparation example, and retained target and requirement
|
|
coverage at their owning seams. The full ordinary `go test ./...` suite passes.
|
|
|
|
**Scope:** Existing consumers and test ownership, without losing execution or
|
|
requirement coverage.
|
|
|
|
1. Remove the unused runner `InspectPrompt`/`InspectProfile` wrappers and their
|
|
wrapper-only tests. Preserve `resolvePromptInspection` for requirement
|
|
selection and profile identity/execution helpers used elsewhere.
|
|
2. Update root inspection, inheritance, namespace, bundled-configuration, and
|
|
source tests for the selected result shape. Preserve literal identity text
|
|
and exact stored-reference behavior. Dereference pointers only after
|
|
checking presence; an unset value is not a zero-valued setting.
|
|
3. Where an old `InspectProfile.EffectiveModelParams` assertion tested backend
|
|
completion or framework timeout, keep that protection on `Prepare`/execution
|
|
or the focused adapter target tests. Do not simply delete the assertion or
|
|
reproduce completed settings in the new inspection result.
|
|
4. Keep `InspectRequirements` tests using the narrow metadata/snapshot seam.
|
|
Retain protection against full definition/target lookups and source access;
|
|
do not replace that seam with the expanded resource report.
|
|
5. Migrate any in-repository examples or helper fixtures that actually consume
|
|
the changed inspection fields. Leave run/prepared-result, output validation,
|
|
appended-message, and extension-client contracts unchanged.
|
|
|
|
**Check:** Run the affected public, configuration, use-case, and example tests
|
|
when their dependency graph is coherent. Search for stale references to
|
|
`ProfileInspection.EffectiveModelParams` and old inspection scalar assumptions;
|
|
do not replace valid execution-result fields with the same name.
|
|
|
|
## Stage 7: Verify Generic JSON And YAML Rendering
|
|
|
|
**Completed:** Real resource results pass the same semantic presence, nested
|
|
provider-data, diagnostics, and omission assertions with standard JSON and YAML
|
|
marshalling. The existing YAML dependency is now a direct test dependency.
|
|
|
|
**Scope:** One focused public serialization contract suite for resource results.
|
|
|
|
1. Inspect real configured resources, then encode the returned values directly
|
|
using `encoding/json` and `go.yaml.in/yaml/v4`. Consumers in the test must not
|
|
build substitute reports, register nested serializers, or switch on fields.
|
|
Use the existing YAML version; update `go.mod`/`go.sum` only as needed to
|
|
reflect its direct test import, without upgrading dependencies.
|
|
2. Decode both outputs into ordinary structures for semantic assertions. Assert
|
|
selected names/nesting and presence, not whitespace, key order, or a golden
|
|
byte snapshot. Use a small set of rich fixtures rather than one fixture per
|
|
field or duplicating configuration validation cases.
|
|
3. Cover absent versus explicit zero/false/empty strings, absent/null versus
|
|
empty collections, and provider-data nulls. Include profile provider maps,
|
|
prompt `inputs`, input `required`, output `repair_attempts`, empty message
|
|
content/cache TTL, and backend capacity/diagnostic fields.
|
|
4. Assert no `extends`, execution-completed profile fields, parsed templates,
|
|
or synthetic diagnostics/endpoints appear. A configured empty reachability
|
|
object remains present, and a recorded queue default is present even when
|
|
it was not originally written by the operator.
|
|
|
|
**Check:** The same semantic cases pass with both ordinary encoders. If tags
|
|
alone fail to preserve a selected case, correct the result representation or
|
|
add narrowly scoped encoding support; do not move adaptation into consumers.
|
|
|
|
## Stage 8: Verify Selection, Isolation, And Offline Boundaries
|
|
|
|
**Completed:** Public namespace, offline reference, ownership, concurrent
|
|
inspection, execution fallback, and retained null/provenance checks pass under
|
|
the race detector. Existing captured-content and requirement tests remain in use.
|
|
|
|
**Scope:** Public behavior risks not already covered by the migrated suite.
|
|
|
|
1. Extend existing namespace tests for backend inspection: scoped slashless ID,
|
|
qualified bypass, no fallback to another namespace, and full selected ID.
|
|
Include a bundled backend through the same API. Reuse existing profile/prompt
|
|
namespace coverage rather than duplicate every selection case three times.
|
|
2. Exercise independence: missing diagnostic default profiles do not prevent
|
|
backend reports; partial profiles do not require endpoints/models; prompt
|
|
reports do not resolve their default profile or schema reference.
|
|
3. Mutate representative returned pointer fields, nested diagnostics, provider
|
|
maps/arrays, and prompt input/message/cache values. Reinspection and later
|
|
preparation must retain the captured values. Include separate concurrent
|
|
inspections using caller-owned results under the race detector, reusing
|
|
existing ownership helpers where suitable.
|
|
4. Use offline boundary doubles or counting files only where needed to prove
|
|
that inspection does not render, read credentials/artifacts/schemas, or call
|
|
a provider. Preserve existing source-lifetime tests and avoid mocks of every
|
|
private call. No live diagnostic or inference requests belong in this suite.
|
|
5. Complete the resource-inspection assertions paired with Stage 2's null
|
|
inheritance case and verify that `InspectConfiguration` still shows the
|
|
retained null and provenance, separately from execution's backend fallback.
|
|
|
|
**Check:** Each test protects a distinct public risk; consolidate overlapping
|
|
new and old cases. Run focused tests and their race-enabled versions when useful.
|
|
Do not introduce benchmark thresholds or additional release gates.
|
|
|
|
## Stage 9: Add Typed Backend Inheritance And Prompt Sources
|
|
|
|
**Completed:** Backend inheritance and the typed prompt mapping constructor
|
|
follow the existing ConfigKit source pattern. Existing focused programmatic
|
|
source and inspection tests pass; composition coverage follows next.
|
|
|
|
**Scope:** Public mapping-constructor implementation and GoDoc.
|
|
|
|
1. Add `Extends *string` to `BackendConfig` and encode it in `BackendSource`
|
|
using the existing profile helper pattern. Update its GoDoc accordingly.
|
|
2. Implement the source-input types and `PromptSource` specified above. Write
|
|
small explicit mapping construction for nested input, message, cache, and
|
|
output values. Preserve supplied order and nil-versus-empty collections.
|
|
3. Pass supported mapping values directly to ConfigKit so its snapshot behavior
|
|
applies. Preserve the other helpers' final-load validation and accepted-input
|
|
contracts. Do not copy through JSON/YAML or add reflection-based encoding.
|
|
4. Document nil/explicit values, sibling inheritance, deferred validation,
|
|
imported file context, and raw mapping escape hatches. Do not give these
|
|
source-input types the inspection result's serialization contract.
|
|
|
|
**Check:** Compare each mapping field with the format reference and the source
|
|
shape table. Incomplete layered records remain expressible, and constructing
|
|
the helper itself neither accesses files nor resolves inheritance.
|
|
|
|
## Stage 10: Verify Typed Sources Through Real Composition
|
|
|
|
**Completed:** Real engine composition tests cover inherited backend and prompt
|
|
records, layered completion, snapshots, explicit values, relative inherited file
|
|
content using ConfigKit's filesystem context, and deferred final validation.
|
|
|
|
**Scope:** Focused source-helper contract tests, not a second ConfigKit suite.
|
|
|
|
1. Extend existing backend-source tests with a real inherited child, preserving
|
|
the child's ID and endpoint/capacity overrides through `InspectBackend`.
|
|
2. Add prompt-source tests using real `NewEngine` composition. Exercise nested
|
|
input/message/output settings, sibling inheritance, source/layer completion,
|
|
explicit false/zero/empty values, nil versus empty lists, and message order.
|
|
Reuse the new resource APIs to observe resolved values and preparation where
|
|
execution behavior is the fact being tested.
|
|
3. Mutate original nested source slices, scalar pointees, and records after
|
|
creating the source. Loading should use ConfigKit's captured source values.
|
|
Keep this representative rather than reimplementing upstream snapshot tests.
|
|
4. Include a relative `content_file` from a typed source with ConfigKit's
|
|
ordinary explicit source context. Use the dependency's existing context
|
|
input setting: construct `filesystem := configkit.NewFilesystem("fixture", fsys)`
|
|
and set `configkit.Input.Filesystem` to
|
|
`&configkit.FilesystemContext{FS: &filesystem, Root: ".", BaseDir: "templates"}`.
|
|
Include an inherited relative message path. Confirm capture uses that context
|
|
without adding a new Promptkit path-setting API.
|
|
5. Confirm malformed final definitions fail at loading, not helper construction;
|
|
rely on existing generic null, inheritance-cycle, and schema validation
|
|
coverage instead of repeating every rejection for every typed helper.
|
|
|
|
**Check:** Run focused source/inspection tests. Existing `ProfileSource` and raw
|
|
mapping workflows remain usable; this stage is not a ConfigKit upgrade or an
|
|
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,
|
|
nullable pointer/collection usage, and minimal direct JSON/YAML rendering.
|
|
Distinguish them from `InspectConfiguration` provenance, requirement
|
|
discovery, `ValidateRequest`, and concrete-request preparation/details.
|
|
2. Document migration from `EffectiveModelParams` to the profile's resource
|
|
fields and from prompt scalar metadata to optional inspection values.
|
|
Consumers needing completed request settings use existing preparation APIs;
|
|
do not add a compatibility execution view to inspection.
|
|
3. Update `docs/formats.md`'s post-handoff profile table and map explanation.
|
|
Show a concrete null migration: a profile with null endpoint/API-key source/
|
|
provider map now permits backend defaults; explicit empty strings still clear
|
|
endpoint/key source, and backend provider maps can be edited through ordinary
|
|
composition. Do not imply a new whole-map suppression replacement exists.
|
|
4. Document typed prompt sources and backend inheritance through the source
|
|
helpers' GoDoc and consumer guidance. Keep exact field contracts in GoDoc
|
|
and the existing format owner rather than parallel exhaustive prose schemas.
|
|
5. Reconcile `docs/internal/sources.md`, `docs/internal/overview.md`, and affected
|
|
runner guidance with configuration-owned resource inspection, retained narrow
|
|
requirement metadata, and simplified execution capture. Adjust architecture
|
|
descriptions only where implemented structure changed; preserve policy and
|
|
the accepted configuration boundary ADR.
|
|
6. Prepare the next minor release note under the existing release procedure.
|
|
At this baseline `v0.19.0` is published, so use `docs/releases/v0.20.0.md`
|
|
unless another version has been published during the sprint. Explain the
|
|
inspection and configuration compatibility changes, link canonical guidance,
|
|
and include the required licensing footer. Update the README release link.
|
|
Do not edit published release notes, tag, push, or run publication commands.
|
|
7. Supply enough migration detail for CommandKit to adopt generic reporting
|
|
without per-field adapters. Changes or publication in CommandKit itself are
|
|
consumer follow-up, not prerequisites or work authorized by this sprint.
|
|
|
|
**Check:** Validate changed local links and terminology. Remove old claims that
|
|
profile inspection is backend-completed, resource results have no JSON contract,
|
|
or null suppresses profile backend fallbacks. Leave unrelated execution and
|
|
ConfigKit composition contracts intact.
|
|
|
|
## Stage 12: Validate And Close The Sprint
|
|
|
|
**Completed:** Audited the selected resource, encoding, source, ownership, and
|
|
null-migration boundaries; added coverage for inherited diagnostics and explicit
|
|
serialization values. With Go 1.27.3, `GOTOOLCHAIN=local`, and `GOWORK=off`,
|
|
`go test -race ./...`, `go vet ./...`, and module tidy verification pass. Changed
|
|
Go files are formatted, local documentation targets and whitespace are checked,
|
|
and the feature roadmap and plan are retained for review.
|
|
|
|
**Scope:** Combined verification and final cleanup of this feature only.
|
|
|
|
1. Confirm that all three inspection operations, every selected result field,
|
|
both generic encoders, helper inheritance, and post-handoff null migration
|
|
are implemented and covered at the appropriate owning boundary. Resolve any
|
|
checks deferred by intermediate compilation failures.
|
|
2. Check that resource lookup uses captured configuration without execution
|
|
completion or a second ConfigKit interpretation; requirement discovery still
|
|
uses its narrow metadata path. Remove obsolete converters/wrappers and
|
|
private fixtures that preserve the old report behavior, without sweeping
|
|
cleanup outside this feature.
|
|
3. Format changed Go files and tidy the module only where imports changed.
|
|
Using the newest locally available Go installation under the development
|
|
guide, run the complete offline suite and vet:
|
|
|
|
```sh
|
|
go test -race ./...
|
|
go vet ./...
|
|
git diff --check
|
|
```
|
|
|
|
Select that toolchain on `PATH`, with `GOTOOLCHAIN=local` and `GOWORK=off`.
|
|
The complete suite includes maintained example tests; do not impose another
|
|
standalone build/example/release-validation gate. No dependency or consumer
|
|
minimum upgrade is selected just to implement this feature.
|
|
4. Inspect all changes for unintended behavior and contracts. In particular,
|
|
preserve ConfigKit source ownership, literal provider nulls, existing request
|
|
overrides, output repair, provider-value support, credential handling, and
|
|
captured-state isolation. Do not add context limits, schema probes, health
|
|
promises, CLI policy, or source-round-trip guarantees.
|
|
5. Verify changed documentation links and review status/diffs under the agent
|
|
commit policy. Mark stages complete with actual validation evidence, commit
|
|
the finished unit, and report any remaining limitations accurately. Keep the
|
|
completed feature roadmap and this plan for the requested implementation
|
|
review; retirement can occur during later release preparation.
|
|
|
|
Completion requires the full selected end state, including generic rendering
|
|
and both deliberate compatibility changes. Passing only the new backend method
|
|
or preserving the old execution-oriented profile report is not completion.
|