Record agreed inheritance reference and presence rules
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
# Built-In Sibling Configuration Inheritance
|
# Built-In Sibling Configuration Inheritance
|
||||||
|
|
||||||
Status: proposed feature design for agreement; not implemented. This document
|
Status: agreed feature design; not implemented. This document defines the intended
|
||||||
defines the intended end state and the remaining architectural decisions. A
|
end state. A separate implementation plan will define execution steps.
|
||||||
separate implementation plan will define execution steps after design agreement.
|
|
||||||
|
|
||||||
## Purpose and priorities
|
## Purpose and priorities
|
||||||
|
|
||||||
@@ -82,8 +81,26 @@ and final schema validation; a referenced parent must be a mapping.
|
|||||||
|
|
||||||
Identity comes from the sibling key, not a copied field in the parent payload.
|
Identity comes from the sibling key, not a copied field in the parent payload.
|
||||||
The child keeps its key. Application fields such as `name` or `id` follow ordinary
|
The child keeps its key. Application fields such as `name` or `id` follow ordinary
|
||||||
combination semantics. Reference-value details and positions without a sibling
|
combination semantics.
|
||||||
namespace are addressed in Open Decisions below.
|
|
||||||
|
### Reference values and positions
|
||||||
|
|
||||||
|
A string-valued `extends` names an exact sibling key, including an empty string
|
||||||
|
if that key exists. Explicit `extends: null` means no parent and cancels a
|
||||||
|
relationship supplied by a lower-precedence source or inherited nested payload.
|
||||||
|
Omitting `extends` contributes no change to an existing relationship during
|
||||||
|
combination; if none remains in the effective mapping, the mapping has no parent.
|
||||||
|
Other value shapes are reference errors.
|
||||||
|
|
||||||
|
Cancellation retains the mapping's own assembled settings but adds no settings
|
||||||
|
from the canceled parent. Like a string reference, the null control field is
|
||||||
|
consumed as structural metadata before typed decoding. This follows existing
|
||||||
|
presence and replacement rules without introducing a deletion operator.
|
||||||
|
|
||||||
|
A string-valued `extends` on the document root or directly on a sequence-element
|
||||||
|
mapping has no enclosing mapping of named siblings and produces a location-bearing
|
||||||
|
reference error. ConfigKit does not search farther up for a namespace. Mappings
|
||||||
|
nested within those structures can still use their own sibling namespaces normally.
|
||||||
|
|
||||||
### Source precedence first, inheritance second
|
### Source precedence first, inheritance second
|
||||||
|
|
||||||
@@ -168,8 +185,8 @@ sort before or after its child without changing the meaning. Breadth-first versu
|
|||||||
recursive traversal is an implementation choice subject to these semantics.
|
recursive traversal is an implementation choice subject to these semantics.
|
||||||
|
|
||||||
Nested mappings inside sequences are also visited, while sequence combination
|
Nested mappings inside sequences are also visited, while sequence combination
|
||||||
continues to replace whole sequences. The treatment of a relationship on a
|
continues to replace whole sequences. A relationship on a sequence element itself
|
||||||
sequence element itself is addressed below.
|
follows the reference-position rules above.
|
||||||
|
|
||||||
## Loading and validation
|
## Loading and validation
|
||||||
|
|
||||||
@@ -212,9 +229,17 @@ may load again explicitly using the existing source-reuse contracts.
|
|||||||
|
|
||||||
Consumers must distinguish direct child input, inherited input, typed defaults,
|
Consumers must distinguish direct child input, inherited input, typed defaults,
|
||||||
and recorded application-derived values. Explicit zero/false/empty/null settings
|
and recorded application-derived values. Explicit zero/false/empty/null settings
|
||||||
remain distinguishable from omission. The representation of inherited presence
|
remain distinguishable from omission. Go zero-value inference is not an acceptable
|
||||||
in the existing query surface is an open decision below; Go zero-value inference
|
substitute.
|
||||||
is not an acceptable substitute.
|
|
||||||
|
An inherited value counts as present configuration input: `IsExplicit` returns
|
||||||
|
true at its destination, while derivation metadata distinguishes inherited input
|
||||||
|
from a direct child declaration. Presence answers whether configuration supplied
|
||||||
|
the value; provenance explains where it came from and how it reached the destination.
|
||||||
|
Typed defaults and application resolver defaults based on absence therefore remain
|
||||||
|
below inherited settings, including inherited zero, false, empty, and null values.
|
||||||
|
The API documentation must explain this effective-input meaning of explicitness;
|
||||||
|
it does not mean the value was written directly at the destination path.
|
||||||
|
|
||||||
Each inherited value retains its originating source and source path, together
|
Each inherited value retains its originating source and source path, together
|
||||||
with the relationship that placed it at the child's destination path. Chains
|
with the relationship that placed it at the child's destination path. Chains
|
||||||
@@ -268,12 +293,13 @@ remains the only consumer boundary.
|
|||||||
Representative examples and behavioral tests should establish source/inheritance
|
Representative examples and behavioral tests should establish source/inheritance
|
||||||
ordering, chains and shared parents, enclosing-first nested resolution, independence
|
ordering, chains and shared parents, enclosing-first nested resolution, independence
|
||||||
from parent/child name sort order, failure diagnostics, partial bases, explicit
|
from parent/child name sort order, failure diagnostics, partial bases, explicit
|
||||||
values versus omission, unchanged sequence/null behavior, origin/resource
|
values versus omission, cancellation of relationships with null, invalid reference
|
||||||
|
positions and types, inherited presence during defaulting, unchanged sequence/null behavior, origin/resource
|
||||||
preservation, result independence, and safe secret inspection. Both loading entry
|
preservation, result independence, and safe secret inspection. Both loading entry
|
||||||
points and supported source representations should share those semantics.
|
points and supported source representations should share those semantics.
|
||||||
|
|
||||||
A new ADR should record the selected inheritance architecture after the open
|
A new ADR should record the selected inheritance architecture.
|
||||||
decisions are resolved. Architecture/deferred-scope documentation must recognize
|
Architecture/deferred-scope documentation must recognize
|
||||||
the new structural responsibility; public API, configuration, consumer, and
|
the new structural responsibility; public API, configuration, consumer, and
|
||||||
internal documentation should describe implemented behavior when it lands.
|
internal documentation should describe implemented behavior when it lands.
|
||||||
Implementation sequencing belongs in a separate future plan. Reserving `extends`
|
Implementation sequencing belongs in a separate future plan. Reserving `extends`
|
||||||
@@ -290,41 +316,3 @@ It can inspect whether each setting was direct, inherited, defaulted, or derived
|
|||||||
follow inherited resource origins, and validate final domain meaning. Missing or
|
follow inherited resource origins, and validate final domain meaning. Missing or
|
||||||
cyclic relationships fail before a usable result is returned. The consumer needs
|
cyclic relationships fail before a usable result is returned. The consumer needs
|
||||||
no separate graph resolver, generic merge pass, or provenance reconstruction.
|
no separate graph resolver, generic merge pass, or provenance reconstruction.
|
||||||
|
|
||||||
## Open Decisions
|
|
||||||
|
|
||||||
### 1. Reference values and positions without a sibling namespace
|
|
||||||
|
|
||||||
**Recommendation:** an omitted `extends` means no relationship; explicit null
|
|
||||||
cancels a relationship supplied by a lower-precedence source or inherited nested
|
|
||||||
payload. A string names an exact sibling key, including an empty string if that
|
|
||||||
key exists. Other value shapes are reference errors. This follows existing
|
|
||||||
presence and replacement rules without introducing a deletion operator.
|
|
||||||
|
|
||||||
A string-valued `extends` on the document root or directly on a sequence-element
|
|
||||||
mapping has no enclosing mapping of named siblings. Report a location-bearing
|
|
||||||
reference error rather than searching elsewhere. Mappings nested within those
|
|
||||||
structures can still use their own sibling namespaces normally. This follows
|
|
||||||
the selected lookup rule, rather than imposing a general ban on nested inheritance.
|
|
||||||
|
|
||||||
**Alternative:** require every present `extends` to be a string. This makes the
|
|
||||||
keyword's value type simpler, but leaves no direct way to cancel an existing
|
|
||||||
relationship while retaining the mapping's other fields. For root/sequence-element
|
|
||||||
references, an ancestor-scope fallback could supply a namespace, but would introduce
|
|
||||||
a positional exception to the agreed immediate-sibling rule; adopting it would
|
|
||||||
require revisiting that decision rather than treating it as an implementation detail.
|
|
||||||
|
|
||||||
### 2. Meaning of inherited presence
|
|
||||||
|
|
||||||
**Recommendation:** an inherited value counts as present input for effective
|
|
||||||
`IsExplicit`/defaulting behavior, with separate derivation metadata distinguishing
|
|
||||||
it from direct child input. This treats inheritance as input expansion, keeps
|
|
||||||
typed and resolver defaults below inherited settings, and avoids consumers
|
|
||||||
reimplementing presence logic. The API must clearly explain that effective
|
|
||||||
presence differs from direct declaration at the destination path.
|
|
||||||
|
|
||||||
**Alternative:** inherited values remain non-explicit at the child path, with
|
|
||||||
a new effective-input-presence query/defaulting rule. This preserves a narrow
|
|
||||||
direct-declaration meaning of explicitness, but requires two presence concepts
|
|
||||||
through the resolver lifecycle and risks defaults overwriting inherited settings
|
|
||||||
unless callers adopt the new query consistently.
|
|
||||||
|
|||||||
Reference in New Issue
Block a user