Refine backend composition and input lifecycle decisions
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
# Registration and execution internals
|
# Registration and execution internals
|
||||||
|
|
||||||
Status: proposed internal design for the finalized consumer API; no implementation
|
Status: proposed internal design for the finalized consumer API; no implementation
|
||||||
has begun. Two public composition seams identified below need resolution before
|
has begun. Runnable-command children and scope-error attachment are selected API
|
||||||
the staged implementation plan is finalized.
|
additions to incorporate into the registration API document. OQ-1 remains open
|
||||||
|
for later discussion before the staged implementation plan is finalized.
|
||||||
|
|
||||||
## Purpose and authority
|
## Purpose and authority
|
||||||
|
|
||||||
@@ -163,6 +164,14 @@ Keep payload and children independent in the private model. Do not introduce a
|
|||||||
new prohibition on runnable commands with children merely because separate leaf
|
new prohibition on runnable commands with children merely because separate leaf
|
||||||
and group constructors are convenient.
|
and group constructors are convenient.
|
||||||
|
|
||||||
|
The selected public addition is `Children []Command` on `CommandSpec[I]`. The
|
||||||
|
registration API currently has no way to combine a handler with children; the
|
||||||
|
private model alone cannot expose the behavior described by
|
||||||
|
[ADR 0006](../adr/0006-command-grammar.md). Capture the child-handle slice using the
|
||||||
|
same ownership and immediate composition checks as `Group`, and enforce the same
|
||||||
|
placement rules at installation. `Group` remains a convenience for non-runnable
|
||||||
|
parents. This addition requires no separate registration mechanism.
|
||||||
|
|
||||||
### Divide validation by responsibility and lifetime
|
### Divide validation by responsibility and lifetime
|
||||||
|
|
||||||
Use one implementation of each core metadata rule:
|
Use one implementation of each core metadata rule:
|
||||||
@@ -211,6 +220,11 @@ template, initialize suite input, or invoke a parser a second time.
|
|||||||
`FlagValues.ApplyTo` selects the original identities and applies their prepared
|
`FlagValues.ApplyTo` selects the original identities and applies their prepared
|
||||||
values to the supplied destination.
|
values to the supplied destination.
|
||||||
|
|
||||||
|
All supplied occurrences undergo conversion, including selectors inapplicable to
|
||||||
|
the selected scope and values supplied alongside help. Scope filtering governs
|
||||||
|
value application and required-value checks, not conversion. An earlier malformed
|
||||||
|
singleton occurrence remains an error even if a later occurrence is valid.
|
||||||
|
|
||||||
Recommend a private identity token per original binding and an invocation-local
|
Recommend a private identity token per original binding and an invocation-local
|
||||||
lookup from token to prepared entry. Handle copies preserve identity; lookalike
|
lookup from token to prepared entry. Handle copies preserve identity; lookalike
|
||||||
bindings get a different token. A private nonzero-sized token object avoids
|
bindings get a different token. A private nonzero-sized token object avoids
|
||||||
@@ -231,8 +245,11 @@ usage outcomes. An integration may wrap those causes with scope/family context
|
|||||||
without parsing error messages or inventing another outcome protocol.
|
without parsing error messages or inventing another outcome protocol.
|
||||||
|
|
||||||
Help still converts supplied occurrences and rejects malformed values through the
|
Help still converts supplied occurrences and rejects malformed values through the
|
||||||
same preparation logic, but does not materialize command/suite input or enforce
|
same preparation logic, but does not materialize the target command's application
|
||||||
execution-required fields. Presence, singleton repetition, and repeated-value
|
or suite input, invoke its validation or execution callbacks, or enforce its
|
||||||
|
execution-required fields. Suite state factories and providers also remain
|
||||||
|
uninvoked. The built-in help command may prepare its own private typed input
|
||||||
|
through the common compiler. Presence, singleton repetition, and repeated-value
|
||||||
semantics remain those of the finalized API and selected grammar.
|
semantics remain those of the finalized API and selected grammar.
|
||||||
|
|
||||||
## One compiled execution path, including help
|
## One compiled execution path, including help
|
||||||
@@ -350,7 +367,7 @@ configuration views with their proper owners.
|
|||||||
`ConfigScope` constructs a public `ckconfig.Scope` and delegates configuration
|
`ConfigScope` constructs a public `ckconfig.Scope` and delegates configuration
|
||||||
command generation to `ckconfig`. It must not construct another config family or
|
command generation to `ckconfig`. It must not construct another config family or
|
||||||
reach into `ckconfig`'s private prepared suite. Its construction-error handoff is
|
reach into `ckconfig`'s private prepared suite. Its construction-error handoff is
|
||||||
the second unresolved seam below.
|
the selected `ckconfig.WithScopeError` operation described below.
|
||||||
|
|
||||||
### Share mechanics where ownership supports them
|
### Share mechanics where ownership supports them
|
||||||
|
|
||||||
@@ -391,21 +408,58 @@ three command sources: built-ins, application declarations, and integrations.
|
|||||||
Include invalid bindings, conflicting roots in either order, an invalid final
|
Include invalid bindings, conflicting roots in either order, an invalid final
|
||||||
member of a batch, nested root-only declarations, absence with retained errors,
|
member of a batch, nested root-only declarations, absence with retained errors,
|
||||||
source metadata edits after capture, and declaration reuse across apps.
|
source metadata edits after capture, and declaration reuse across apps.
|
||||||
|
Include runnable parents with children through `CommandSpec.Children`, applying
|
||||||
|
the same capture, collision, and placement checks as ordinary groups.
|
||||||
|
|
||||||
For execution, check wrapped wiring versus input failures, fresh repeatable
|
For execution, check wrapped wiring versus input failures, fresh repeatable
|
||||||
collections, pointer-shaped scope inputs with shared state, scope-aware validation,
|
collections, pointer-shaped scope inputs with shared state, scope-aware validation,
|
||||||
help without factories/providers, and metadata refresh without callback replay.
|
help without target application/suite factories or providers, and metadata refresh
|
||||||
|
without callback replay. Check that supplied but inapplicable selectors still
|
||||||
|
undergo conversion, including on help paths, while the built-in help command can
|
||||||
|
prepare its own private input through the common compiler.
|
||||||
Evidence for the internal path itself can inspect the shared installer/compiler;
|
Evidence for the internal path itself can inspect the shared installer/compiler;
|
||||||
do not turn a private function name or exact allocation count into a public
|
do not turn a private function name or exact allocation count into a public
|
||||||
contract. These are review targets for the future implementation, not a request
|
contract. These are review targets for the future implementation, not a request
|
||||||
to add or run tests during this planning pass.
|
to add or run tests during this planning pass.
|
||||||
|
|
||||||
|
## Resolved scope-error handoff (OQ-2)
|
||||||
|
|
||||||
|
The selected `Scope[I, S]` includes private adapter-construction issues owned by
|
||||||
|
`ckconfig`. Before the selected addition below, `ckprompt.ConfigScope` could not
|
||||||
|
attach its original nil-loader error through supported public contracts. An
|
||||||
|
`Acquire == nil` check alone is insufficient: narrowing `Operations` to empty makes a scope
|
||||||
|
metadata-only, while the original invalid loader must remain an error. Wrapping
|
||||||
|
the nil loader in a non-nil acquisition closure would incorrectly defer it to
|
||||||
|
invocation. A core `WithError` only accepts a `Command`, not a scope.
|
||||||
|
|
||||||
|
**Selected:** add the integration-owned operation
|
||||||
|
`ckconfig.WithScopeError[I, S](scope Scope[I, S], err error) Scope[I, S]`.
|
||||||
|
It returns a scope retaining the original issue, preserving supported error
|
||||||
|
identity. Repeated attachments preserve earlier causes and leave the original
|
||||||
|
scope unchanged; a nil error preserves the scope. Retained causes survive scope
|
||||||
|
copies and narrowing of `Operations`. The family factory collects those issues
|
||||||
|
into its command declaration before capability selection or absence can discard
|
||||||
|
them. `ConfigScope` uses this for its original loader validation and
|
||||||
|
otherwise fills the ordinary public scope fields.
|
||||||
|
|
||||||
|
This mirrors the accepted core retained-error model at the boundary that needs
|
||||||
|
it. It does not add scope installation, expose private representations, or move
|
||||||
|
PromptKit types into the core. Scope capture still occurs at the existing family
|
||||||
|
factory; this operation is evidence attachment rather than a new lifecycle.
|
||||||
|
|
||||||
|
**Alternative considered:** give the public scope declaration an explicit
|
||||||
|
construction-error field, consumed by the family factory alongside provider metadata. This is simple
|
||||||
|
and permits application-created adapters to supply errors directly. It expands
|
||||||
|
mutable public representation and requires defining preservation/combination of
|
||||||
|
multiple errors; the opaque attachment operation keeps those details private.
|
||||||
|
|
||||||
## Open Questions
|
## Open Questions
|
||||||
|
|
||||||
The main internal design can use the existing finalized API. The following two
|
OQ-1 remains unresolved; its recommendation and alternatives below are retained
|
||||||
seams need an explicit API clarification or small approved extension. Do not
|
for later discussion. The selected API additions above need to be reflected in
|
||||||
resolve them with private-module imports, dummy providers, reflection, or hidden
|
the registration API document before implementation planning is finalized. Do not
|
||||||
global state.
|
resolve the remaining question with private-module imports, dummy providers,
|
||||||
|
reflection, or hidden global state.
|
||||||
|
|
||||||
### OQ-1: Retaining core binding errors when a family is absent
|
### OQ-1: Retaining core binding errors when a family is absent
|
||||||
|
|
||||||
@@ -448,35 +502,3 @@ This needs no new API and is proportionate to installed behavior, but limits the
|
|||||||
meaning of suite validation before absence to integration metadata and retained
|
meaning of suite validation before absence to integration metadata and retained
|
||||||
adapter issues rather than all unused bindings. Choose it deliberately,
|
adapter issues rather than all unused bindings. Choose it deliberately,
|
||||||
rather than silently making empty capabilities swallow invalid declarations.
|
rather than silently making empty capabilities swallow invalid declarations.
|
||||||
|
|
||||||
### OQ-2: Retaining errors in a scope constructed by another integration
|
|
||||||
|
|
||||||
The selected `Scope[I, S]` includes private adapter-construction issues owned by
|
|
||||||
`ckconfig`. `ckprompt.ConfigScope` returns that scope type, but cannot attach its
|
|
||||||
original nil-loader error through supported public contracts. An `Acquire == nil`
|
|
||||||
check alone is insufficient: narrowing `Operations` to empty makes a scope
|
|
||||||
metadata-only, while the original invalid loader must remain an error. Wrapping
|
|
||||||
the nil loader in a non-nil acquisition closure would incorrectly defer it to
|
|
||||||
invocation. A core `WithError` only accepts a `Command`, not a scope.
|
|
||||||
|
|
||||||
**Recommendation:** approve an integration-owned operation, schematically
|
|
||||||
`ckconfig.WithScopeError[I, S](scope Scope[I, S], err error) Scope[I, S]`.
|
|
||||||
It returns a scope retaining the original issue, preserving supported error
|
|
||||||
identity; a nil error preserves the scope. The family factory collects those
|
|
||||||
issues into its command declaration before capability selection or absence can
|
|
||||||
discard them. `ConfigScope` uses this for its original loader validation and
|
|
||||||
otherwise fills the ordinary public scope fields.
|
|
||||||
|
|
||||||
This mirrors the accepted core retained-error model at the boundary that needs
|
|
||||||
it. It does not add scope installation, expose private representations, or move
|
|
||||||
PromptKit types into the core. Scope capture still occurs at the existing family
|
|
||||||
factory; this operation is evidence attachment rather than a new lifecycle.
|
|
||||||
|
|
||||||
**Alternative:** give the public scope declaration an explicit construction-error
|
|
||||||
field, consumed by the family factory alongside provider metadata. This is simple
|
|
||||||
and permits application-created adapters to supply errors directly. It expands
|
|
||||||
mutable public representation and requires defining preservation/combination of
|
|
||||||
multiple errors; the opaque attachment operation keeps those details private.
|
|
||||||
|
|
||||||
Neither seam requires a general plugin system. Confirm their resolutions before
|
|
||||||
turning this design and the module roadmap into ordered implementation stages.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user