Link the finalized registration backend design
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
# Unified command registration API
|
||||
|
||||
Status: finalized API design; implementation is pending. The declarations,
|
||||
consumer examples, and design checks below define the selected target API.
|
||||
consumer examples, and design checks below define the selected target API,
|
||||
including the additions and clarifications selected in the finalized backend
|
||||
design.
|
||||
No implementation is authorized by this document alone.
|
||||
|
||||
## Purpose and authority
|
||||
@@ -23,7 +25,10 @@ boundaries and convenient integration registration.
|
||||
captured-declaration model, optional-family namespace lifetime, and separated
|
||||
input/shared-state lifetimes. The [architecture policy](../policy/architecture.md)
|
||||
reflects those boundaries. The [module roadmap](modules.md) tracks extraction
|
||||
work; this API design remains a target rather than implemented behavior.
|
||||
work. The finalized [backend design](registration-backend.md) owns internal
|
||||
structure and shared implementation mechanics. Its resolved composition choices
|
||||
are incorporated below; this API design remains a target rather than implemented
|
||||
behavior.
|
||||
|
||||
Design for the best consumer API without preserving current implementation
|
||||
signatures or machinery. Existing code can supply evidence and reusable work,
|
||||
@@ -109,8 +114,10 @@ A failed `New` yields no usable application. A failed `Register` leaves the
|
||||
existing registry intact. No rollback guarantee spans separate registration calls.
|
||||
|
||||
Declaration construction, installation, help, and version do not invoke provider
|
||||
acquisition or invocation input/context factories. They do not validate files,
|
||||
credentials, or application configuration. Invalid wiring fails at installation;
|
||||
acquisition or application/suite input/state factories. Built-in help may prepare
|
||||
its own private typed input through the common compiler, without initializing the
|
||||
target command or invoking its validation/execution callbacks. These paths do not
|
||||
validate files, credentials, or application configuration. Invalid wiring fails at installation;
|
||||
an upstream error returned by a valid provider remains an invocation result.
|
||||
|
||||
An originally nil loader remains invalid wiring even if an adapter would wrap
|
||||
@@ -171,8 +178,14 @@ The selected empty-suite behavior is:
|
||||
|
||||
Use an explicit `commandkit.NoCommand()` declaration for intentional absence.
|
||||
Core installation skips it. A zero-value `Command` remains invalid. Integration
|
||||
factories validate or retain wiring errors before representing an empty family
|
||||
as a no-op; absence must not swallow errors. A no-op does not reserve a namespace.
|
||||
factories retain adapter-construction errors before representing an empty family
|
||||
as a no-op. Validate bindings needed by generated commands; unused selector
|
||||
bindings are ignored when they contribute to no generated inspection command.
|
||||
Integration-owned scope identifiers, applicability references, and enabled-provider
|
||||
wiring still undergo validation. Ignoring unused bindings does not erase retained
|
||||
adapter errors. This is the selected [unused-binding resolution](registration-backend.md#resolved-unused-binding-validation-oq-1).
|
||||
A no-op does not reserve a namespace, and `NoCommand()` needs no validation-bearing
|
||||
overload or separate public declaration validator.
|
||||
|
||||
## Capture, reuse, and invocation inputs
|
||||
|
||||
@@ -273,6 +286,7 @@ type CommandSpec[I any] struct {
|
||||
Name string
|
||||
Summary string
|
||||
Description string
|
||||
Children []Command
|
||||
NewInput func() I
|
||||
Flags []Flag[I]
|
||||
Arguments []Argument[I]
|
||||
@@ -367,6 +381,17 @@ installed tree, extract its handlers, or append children after capture. Collecti
|
||||
in `CommandSpec`, groups, and defaults are captured as appropriate; runtime
|
||||
closure state and diagnostic writer effects remain caller-owned.
|
||||
|
||||
### Runnable parents and captured children
|
||||
|
||||
`CommandSpec.Children` combines a typed handler with child declarations. Capture
|
||||
its child-handle slice and apply the same immediate composition, collision, and
|
||||
installation placement checks used by `Group`. A runnable parent follows its
|
||||
handler and operand requirements on bare invocation; help describes the parent
|
||||
and children under [ADR 0006](../adr/0006-command-grammar.md). `Group` remains the
|
||||
convenience for a non-runnable parent. Neither form permits mutation or child
|
||||
append operations after capture. The [backend design](registration-backend.md#immutable-declaration-records)
|
||||
uses the same captured representation and installation path for both.
|
||||
|
||||
### Retained errors, placement, and no-ops
|
||||
|
||||
`WithError` returns a new captured declaration retaining a non-nil error alongside
|
||||
@@ -565,6 +590,8 @@ func FromConfigKit[I, S, T any](
|
||||
load func(context.Context, Selection, I, S) (*configkit.Result[T], error),
|
||||
) Scope[I, S]
|
||||
|
||||
func WithScopeError[I, S any](scope Scope[I, S], err error) Scope[I, S]
|
||||
|
||||
func Command[I, S any](suite Suite[I, S]) commandkit.Command
|
||||
|
||||
func AppCommand[T any](
|
||||
@@ -581,9 +608,11 @@ validation diagnostics at invocation time, preserving current selected reports
|
||||
and classifications rather than implementing a second configuration engine.
|
||||
|
||||
An empty selector scope list applies to all registered scopes; a nonempty list
|
||||
identifies its applicable registered scopes. Unknown identifiers and reserved
|
||||
standard-flag collisions are declaration errors. Scope identifiers, capability
|
||||
selection, defaults, and aggregate availability follow
|
||||
identifies its applicable registered scopes. Unknown scope identifiers are
|
||||
declaration errors. Bindings used by generated commands undergo core validation,
|
||||
including standard-flag collisions; unused selector bindings follow the selected
|
||||
absence/unused-binding rule above. Scope identifiers, capability selection,
|
||||
defaults, and aggregate availability follow
|
||||
[ADR 0009](../adr/0009-configuration-scopes.md). Non-applicable selectors are not
|
||||
applied to a scope's input; this adds no new unused-selector rejection policy.
|
||||
`CheckInput` receives the registered name of each requested scope alongside its
|
||||
@@ -605,6 +634,21 @@ arguments nor demands a forwarding wrapper from the caller. A nil loader becomes
|
||||
a retained `config`/`app` declaration error. The full suite is used for composition;
|
||||
there is no incremental scope append operation after installation.
|
||||
|
||||
### Retained scope errors
|
||||
|
||||
`ckconfig.WithScopeError` returns a scope retaining a non-nil construction error
|
||||
alongside earlier causes, leaving the original scope unchanged. A nil error
|
||||
preserves the scope. Retained causes preserve supported `errors.Is`/`errors.As`
|
||||
identity across scope copies and narrowing of `Operations`. The family factory
|
||||
collects those issues into its command declaration before capability selection
|
||||
can discard them; no acquisition callback runs to discover a construction error.
|
||||
|
||||
`ckprompt.ConfigScope` uses this public operation to retain original loader errors
|
||||
without accessing private `ckconfig` state. It otherwise declares the ordinary
|
||||
scope fields and capabilities. The [scope-error resolution](registration-backend.md#resolved-scope-error-handoff-oq-2)
|
||||
records the rationale and rejected alternative; the operation adds no new scope
|
||||
installation lifecycle.
|
||||
|
||||
## Selected PromptKit integration declarations
|
||||
|
||||
The `ckprompt` package uses `ckconfig` selections and scope contracts through its
|
||||
@@ -662,7 +706,9 @@ maps the owning library's public diagnostics into core-owned `Diagnostic` values
|
||||
Definition providers preserve diagnostics even when a named lookup fails.
|
||||
|
||||
Consumers may leave either definition callback nil to omit that capability.
|
||||
A valid suite with both nil is an explicit no-op after eager declaration validation.
|
||||
A suite with both callbacks nil contributes no commands and ignores unused
|
||||
selector bindings. It returns a no-op retaining any adapter-construction errors;
|
||||
those errors still fail installation.
|
||||
A nil loader supplied to `FromEngine` is invalid wiring, not missing capability;
|
||||
setting its callbacks nil does not erase the retained error. For prompt lookup,
|
||||
the adapter passes the requested version value to PromptKit, with omission using
|
||||
@@ -706,7 +752,18 @@ succeed. The no-call rows remain unconditional for CommandKit-owned paths.
|
||||
| Configuration inspection of several scopes | Once per selected scope | Once, shared by selected scopes | Requested scopes, in selected operation order |
|
||||
| Named definition inspection | Once for the selected command | Once for that invocation | Selected inspection callback |
|
||||
|
||||
The factory counts describe application inputs and suite input/state. Built-in
|
||||
help may prepare its own private input through the common compiler; it still
|
||||
leaves the target application's and suites' factories, validation/execution
|
||||
callbacks, and providers uninvoked.
|
||||
|
||||
Input conversion and scope/capability preflight use metadata without acquisition.
|
||||
All supplied occurrences on an installed command undergo conversion, including
|
||||
selectors inapplicable to the requested scope and values supplied with help.
|
||||
Scope filtering affects value application and required-value checks, not
|
||||
conversion; an earlier malformed singleton occurrence remains an error even if a
|
||||
later one is valid.
|
||||
|
||||
For configuration execution, initialize and populate each requested scope input,
|
||||
then run its `CheckInput`; initialize the shared state before acquisition after
|
||||
input checks succeed. The input/state callbacks do not run for unselected scopes
|
||||
@@ -1126,7 +1183,7 @@ of arbitrary effects inside application callbacks.
|
||||
| --- | --- |
|
||||
| `ckconfig.Command(ckconfig.Suite[struct{}, struct{}]{})` | Error: no configuration scopes |
|
||||
| One named scope with empty operations and nil acquisition | Success; `config scopes` describes it, no inspection verbs supplied by that scope |
|
||||
| Valid definition suite with no callbacks | Explicit absence, no namespace claimed |
|
||||
| Definition suite with no callbacks and unused selector bindings | Explicit absence, unused bindings ignored; retained adapter errors still fail |
|
||||
| `NoCommand()` beside ordinary children | Skipped, no placeholder help item |
|
||||
| `WithError(NoCommand(), sentinel)` | Error retaining sentinel identity |
|
||||
| Zero `Command{}` at the root or as a child | Declaration error |
|
||||
@@ -1219,10 +1276,13 @@ The documentation alignment is complete:
|
||||
| [ADR 0001 status](../adr/0001-command-dispatch-and-inputs.md#status) | Remains accepted, with refinements recorded in ADR 0011 and its decision text preserved |
|
||||
| [ADR 0010](../adr/0010-optional-integration-modules.md) | Core/integration dependency boundaries remain in effect; ADR 0011 refines registration and supersedes the migration-guide requirement for this unreleased prototype |
|
||||
| [Architecture policy](../policy/architecture.md) | Uniform installed-family ownership, optional integration facades, and declaration/input boundaries |
|
||||
| [Module roadmap](modules.md) | Final API selected; documentation alignment completed; extraction and release adoption still pending |
|
||||
| [Module roadmap](modules.md) | Final API and backend design selected; extraction and release adoption still pending |
|
||||
| [Backend design](registration-backend.md) | Shared internal pipeline, runnable children, scope-error attachment, unused-binding validation, and both composition-question resolutions |
|
||||
|
||||
A staged module implementation plan remains to be written from this finalized
|
||||
API and the module roadmap. It should specify eager capture, error retention,
|
||||
neutral bindings, scope isolation, maintained examples, and release adoption.
|
||||
API, the finalized [backend design](registration-backend.md), and the module
|
||||
roadmap. Both composition questions are resolved. The plan should specify eager
|
||||
capture, error retention, neutral bindings, scope isolation, maintained examples,
|
||||
and release adoption.
|
||||
The documentation alignment neither implements these changes nor authorizes
|
||||
implementation by itself.
|
||||
|
||||
Reference in New Issue
Block a user