Clarify inspection input ownership and documentation

This commit is contained in:
2026-10-11 13:07:00 +00:00
parent cec4da69d3
commit 7ce2fc0bf2
8 changed files with 67 additions and 27 deletions

View File

@@ -103,10 +103,12 @@ values.
Use `ckconfig.Command(ckconfig.Suite[I, S]{...})` when the application needs
multiple named scopes, selector flags, scope-aware input checks, or shared
acquisition state. Each selected scope receives its own initialized input. The
suite's `NewState` runs once for the inspection invocation after selected input
checks pass, and the resulting state is shared by selected acquisitions. The
application owns the state type and what it caches. `ckconfig.FromConfigKit`
acquisition state. Input is initialized separately for each selected scope;
state is shared by selected acquisitions. Factory results remain caller-owned,
so separate initialization calls do not guarantee distinct objects. See
[ckconfig.Suite's GoDoc](../../integrations/ckconfig/contracts.go) for factory
timing, omitted-factory zero values (including nil pointers), and ownership.
The application owns the state type and what it caches. `ckconfig.FromConfigKit`
adapts a typed ConfigKit loader without calling it during construction.
The `config` family provides scope discovery, validation, native effective YAML,
@@ -124,16 +126,19 @@ it under `config`; it does not install named definition commands.
inspection callbacks. Set its `NewInput`, `NewState`, selectors, or validation
when the application needs them, then pass `ckprompt.Command(suite)` to core.
Prompt and profile capabilities can be installed independently by providing
only the corresponding callback. Each selected inspection gets a fresh input
and one shared state value for that invocation. The loader receives the
invocation context, explicitly supplied selection, input, and state. The adapter
only the corresponding callback. Each selected inspection prepares one input
and one state value when those steps are reached. See
[ckprompt.Suite's GoDoc](../../integrations/ckprompt/adapters.go) for factory
timing, omitted-factory zero values, and caller-owned objects and effects.
The loader receives invocation context, explicitly supplied selection, input,
and state. The adapter
uses PromptKit's public inspection methods and preserves acquisition diagnostics
and error identity.
Definition inspection does not execute a prompt, contact a model provider, or
resolve credential values. Credential fields in reports identify environment
variable names and requirements only; they do not report credential
availability.
CommandKit-owned inspection code does not execute prompts, contact model
providers, or resolve credential values; application loaders and direct callbacks
retain their own effects. The [CLI reference](../cli.md#promptkit-definition-inspection)
owns the inspection boundary and credential-report semantics.
The [composed example](../../integrations/ckprompt/examples/composed/README.md)
combines app and PromptKit config scopes, independently registers profile

View File

@@ -126,7 +126,17 @@ require callbacks to run after failure.
## R3: Make public documentation precise about ownership and the final API
**Status:** Open. **Priority:** P2.
**Status:** Completed (2026-10-11). **Priority:** P2.
**Completed work:** the suites' GoDoc now specifies initialization timing,
omitted-factory zero values (including nil pointers), early-failure limits, and
caller ownership of objects, aliases, and effects. Family GoDoc and consumer
guidance link to those owners. Inspection claims are qualified, the composed
example describes `NewInput`/`NewState`, and `Scope.Summary` no longer promises
discovery output. Reviewed against current preparation/acquisition code and the
example; current consumer/example Markdown has no obsolete context API names.
Changed local links/fragments and whitespace checks pass. Runtime rules and
report fields are unchanged.
**Evidence and corrections:**

View File

@@ -69,7 +69,7 @@ type View struct {
type Scope[I, S any] struct {
// Name identifies the scope in CLI selection and reports.
Name string
// Summary is shown when the scope is listed.
// Summary describes the scope. Scope discovery reports name and operations only.
Summary string
// Operations selects the standard handlers exposed for this scope.
Operations []Operation
@@ -89,10 +89,21 @@ type Selector[I any] struct {
// Suite declares the typed input, shared state, selectors, and configuration
// scopes used to assemble configuration commands.
//
// Input initialization is separate for each selected scope; state is shared
// by that invocation's acquisitions. Factory results and callback effects remain
// caller-owned: Command does not deep-copy arbitrary objects or repair aliases
// returned by factories. Core-owned repeated flag collections are copied when
// applied to separate inputs. Factories are not invoked during construction,
// installation, help, version, or scope discovery, and need not run after failure.
type Suite[I, S any] struct {
// NewInput creates fresh input storage for each selected scope.
// NewInput is called once for each selected scope reached after operation
// preflight, before applying its selectors and calling CheckInput.
// If nil, input is the zero value of I, including nil for pointer types.
NewInput func() I
// NewState creates shared acquisition state once per inspection invocation.
// NewState is called once when acquisition is reached, after all selected
// inputs pass their checks. The result is shared by selected acquisitions.
// If nil, state is the zero value of S, including nil for pointer types.
NewState func() S
// Selectors declares typed flags and their applicable scopes.
Selectors []Selector[I]

View File

@@ -43,9 +43,9 @@ type preparedSuite[I, S any] struct {
// Command eagerly captures a configuration suite as a root-only config family.
// It copies suite slices, retains callback references, and returns a reusable
// declaration; installation does not invoke factories or providers. During an
// inspection, it creates separate input for each selected scope, validates
// those inputs before acquisition, and creates shared state once for that
// invocation.
// inspection, it initializes input separately for each selected scope and
// validates those inputs before acquisition. Suite documents factory timing,
// zero values, shared state, and caller ownership of returned objects.
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
prepared := captureSuite(suite)
if len(prepared.scopes) == 0 {

View File

@@ -21,8 +21,11 @@ Add `ckprompt.ConfigScope(loadEngine)` to the scopes passed to
the `config` family. Install `ckprompt.Command(ckprompt.FromEngine(loadEngine))`
separately for named prompt and profile inspection. `FromEngine` supplies
PromptKit-backed callbacks; applications may provide their own callbacks with
`ckprompt.Suite`. Inspection does not execute prompts, contact model providers,
or resolve credentials. The maintained
`ckprompt.Suite`. CommandKit-owned inspection code does not execute prompts,
contact model providers, or resolve credentials; application loaders and direct
callbacks retain their own effects. See the
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#promptkit-definition-inspection)
for the inspection boundary and report semantics. The maintained
[composed example](examples/composed) shows complete application wiring.
## License and attribution

View File

@@ -33,10 +33,17 @@ type ProfileRequest struct {
// Suite describes application-owned input, shared state, and named inspection
// capabilities. Its private issues retain adapter construction failures.
// Factory results and callback effects remain caller-owned: Command does not
// deep-copy arbitrary objects or repair aliases returned by factories.
// Factories are not invoked during construction, installation, help, or version,
// and need not run after failure.
type Suite[I, S any] struct {
// NewInput creates input storage once for the selected definition command.
// NewInput is called once when definition input preparation is reached,
// before applying selectors and calling CheckInput.
// If nil, input is the zero value of I, including nil for pointer types.
NewInput func() I
// NewState creates shared inspection state once for that invocation.
// NewState is called once when inspection is reached, after input checks
// pass. If nil, state is the zero value of S, including nil for pointer types.
NewState func() S
// Selectors declares the original typed flags accepted by definition commands.
Selectors []commandkit.Flag[I]

View File

@@ -26,8 +26,8 @@ type definitionInput[I any] struct {
// Command captures the optional named PromptKit inspection tree and adds only
// the inspection capabilities present in suite. It adds no configuration
// family; callers compose ConfigScope independently. Construction and
// installation do not run suite callbacks. A selected definition command gets
// its own input and one shared state value for that invocation.
// installation do not run suite callbacks. Suite documents invocation input
// and state initialization, zero values, and caller ownership of returned objects.
func Command[I, S any](suite Suite[I, S]) commandkit.Command {
if suite.InspectPrompt == nil && suite.InspectProfile == nil {
command := commandkit.NoCommand()

View File

@@ -13,6 +13,10 @@ go run . session restore session-42 --campaign spring
The sources and session store are small in-memory fixtures. `--campaign` is a
typed selector shared by the app and PromptKit configuration scopes. Their
scope contexts share a per-invocation cache created by `ConfigSuite.NewContext`.
Prompt/profile inspection has its own invocation context and composes the same
application and engine loader functions.
`ckconfig.Suite[*inspectionInput, *runCache]` uses `NewInput` to initialize each
selected scope's input separately and `NewState` to create one cache shared by
that invocation's acquisitions. Prompt/profile inspection prepares its input and
cache independently for its invocation, using the same application and engine
loader functions. See the
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md)
and the suites' GoDoc for initialization timing and ownership.