Settle sequence validation and absent value behavior
This commit is contained in:
@@ -267,9 +267,9 @@ removal directive is needed.
|
||||
Application registrations continue to constrain the replacement collection.
|
||||
If the application requires `id`, declaring `name` is invalid under every mode.
|
||||
The policy reset above applies when a sequence is actually replaced; effects of
|
||||
absent contributions, null collections, and kind mismatches remain under OD-6.
|
||||
These structural rules do not settle final-result enforcement for YAML-only
|
||||
identity declarations, which remains the OD-1 follow-up.
|
||||
absent contributions, null collections, and kind mismatches are settled in OD-6.
|
||||
YAML-only identity declarations receive assembly-time enforcement, as settled
|
||||
in OD-1 below.
|
||||
|
||||
### Combination Scope, Declarations, And Ordering
|
||||
|
||||
@@ -342,8 +342,8 @@ For example, lower `[A, B, C]` and higher `[C*, A*, D]` produce
|
||||
preserves its position; whole-sequence replacement gives the higher tier control
|
||||
of the complete sequence order.
|
||||
|
||||
OD-5 settles default selection and operation naming. Absent contributions, empty
|
||||
sequences, null, and kind mismatches remain under OD-6.
|
||||
OD-5 settles default selection and operation naming. OD-6 settles absent
|
||||
contributions, empty sequences, null, and kind mismatches.
|
||||
|
||||
### Mode Names And Effective-Identity Defaults
|
||||
|
||||
@@ -447,13 +447,13 @@ This is an authoritative constraint, distinct from an application default that
|
||||
only fills an omission. Configuration can define identity for collections
|
||||
without an application-owned constraint. Omitted configuration identity uses a
|
||||
registered definition when present, and an explicit matching declaration is
|
||||
accepted, as settled in OD-2. The final-result guarantee for
|
||||
application-owned constraints is settled below; YAML-only enforcement remains
|
||||
an open follow-up to OD-1.
|
||||
accepted, as settled in OD-2. OD-1 below distinguishes the final-result guarantee
|
||||
for application-owned constraints from assembly-time enforcement for YAML-only
|
||||
declarations.
|
||||
|
||||
### Final-Result Guarantee For Application Registrations
|
||||
|
||||
**OD-1: settled for application-owned constraints.**
|
||||
**OD-1: settled, including the YAML-only follow-up below.**
|
||||
|
||||
> On successful loading, the final effective collections covered by application
|
||||
> registrations satisfy their declared identity constraints.
|
||||
@@ -466,8 +466,9 @@ does not require every intermediate callback state to satisfy the constraint
|
||||
and does not extend to caller mutations after loading returns.
|
||||
|
||||
Keep the promise limited to the declared identity constraints. It does not by
|
||||
itself require registered paths to exist or settle null and non-sequence
|
||||
handling; those collection boundaries remain under OD-6. Final validation examines
|
||||
itself require registered paths to exist or be non-null. Identity validation checks
|
||||
actual sequences; the application schema and validation determine whether absence,
|
||||
null, or another shape is acceptable, as settled in OD-6. Final validation examines
|
||||
effective typed values, while assembly-time checks retain their role in
|
||||
validating authored contributions. A final scalar value alone does not prove
|
||||
that the field was explicitly supplied in a source.
|
||||
@@ -477,7 +478,52 @@ provide the implementation foundation. Diagnostics should identify the affected
|
||||
collection and item paths, using available origin information without exposing
|
||||
identity values. The guarantee requires neither a new mutation-history system
|
||||
nor exact causal reconstruction for records supplied by defaults or callbacks.
|
||||
Final enforcement for identities declared only in YAML is not settled here.
|
||||
|
||||
### Assembly-Time Enforcement For YAML-Only Identities
|
||||
|
||||
Enforce identities declared only in YAML during structural composition and
|
||||
precedence assembly. They do not carry a final-result guarantee after later
|
||||
defaulting, inheritance, CLI overrides, or application resolution. Those stages
|
||||
may produce a collection that no longer satisfies a YAML-only identity, including
|
||||
duplicate identities. OD-7 still owns whether any additional lifecycle stages
|
||||
participate in the new combination operations.
|
||||
|
||||
Applications requiring a final identity constraint register it through the
|
||||
application-owned interface. This keeps YAML declarations aligned with the
|
||||
structural operations they control and avoids extending their policy lifetime
|
||||
through later replacements, callbacks, and nested-record changes solely for
|
||||
final validation.
|
||||
|
||||
### Absence, Empty Sequences, Null, And Kind Mismatches
|
||||
|
||||
**OD-6: settled.**
|
||||
|
||||
At a collection's precedence boundary:
|
||||
|
||||
| Higher-tier contribution | `replace` | `append` / `upsert` |
|
||||
| --- | --- | --- |
|
||||
| Absent | Leave the lower value unchanged | Leave the lower value unchanged |
|
||||
| Explicit `[]` | Clear the sequence | Contribute no records |
|
||||
| Explicit null or another non-sequence value | Ordinary replacement, subject to application schema | Error: the operation requires a sequence |
|
||||
|
||||
A declaration alone does not clear a collection. An optional import selecting
|
||||
nothing contributes nothing; it does not erase records supplied elsewhere.
|
||||
An absent lower collection can be initialized by an incoming sequence under
|
||||
any mode, subject to identity requirements. An explicitly null or other
|
||||
non-sequence lower value is distinct from absence: append and upsert against it
|
||||
fail, while replacement remains available. An empty incoming sequence does not
|
||||
bypass these kind checks or the operation's identity requirements.
|
||||
|
||||
With effective identity available, an omitted mode selects upsert. Consequently,
|
||||
`prompts: []` alone does not clear an identified collection. Clearing it requires
|
||||
explicit `mode: replace`. Replacing an identified collection with null likewise
|
||||
requires explicit replacement and an application schema that permits null.
|
||||
|
||||
An application identity registration does not itself require the collection path
|
||||
to exist or be non-null, and does not independently reject non-sequence values.
|
||||
Identity validation checks actual sequences; application schema and validation
|
||||
own the permitted shape. Null as a collection is distinct from a present null
|
||||
identity component inside a record, which is valid under OD-3.
|
||||
|
||||
## Architectural Direction
|
||||
|
||||
@@ -518,42 +564,6 @@ design and test sequencing belong to that later plan.
|
||||
|
||||
## Open Decisions
|
||||
|
||||
### OD-1 Follow-Up. Final Validation For YAML-Only Identity Declarations
|
||||
|
||||
Application-registered collections have the settled final-result guarantee
|
||||
above. Should a configuration-only identity declaration carry the same
|
||||
guarantee, or govern structural assembly alone?
|
||||
|
||||
**Discussion basis:** Declaration scope and identity-policy lifetime are settled
|
||||
in OD-2 and OD-3. Revisit final enforcement using the effective identity of each
|
||||
retained collection. The application-owned guarantee remains independent of
|
||||
this choice.
|
||||
|
||||
**Alternatives:** Applying the same final check to YAML-declared identities
|
||||
would give both declaration forms consistent enforcement, but requires carrying
|
||||
the effective policy through later lifecycle stages, including nested records.
|
||||
Limiting YAML-only identity to assembly keeps policy lifetime narrower, but later
|
||||
operations could produce a final collection that no longer satisfies that
|
||||
identity declaration.
|
||||
|
||||
### OD-6. What Do Absence, Empty Sequences, And Null Mean?
|
||||
|
||||
Can a declaration selecting nothing affect a lower collection? How do explicit
|
||||
empty sequences, null, and non-sequence values interact with all three operations?
|
||||
|
||||
**Initial recommendation:** An optional import selecting nothing contributes
|
||||
nothing and does not clear lower values. An explicitly supplied empty sequence
|
||||
with whole-sequence replacement can clear a collection; append or replacement
|
||||
by identity with an empty sequence contributes no records. Preserve the
|
||||
distinction between absence and supplied values. Decide
|
||||
null and kind-mismatch handling explicitly rather than silently treating them
|
||||
as empty sequences.
|
||||
|
||||
**Alternative:** Treat an explicitly declared replacement operation as a reset
|
||||
even when its import selects nothing. This provides a compact clearing mechanism,
|
||||
but makes an optional missing file or empty search destructive. Keeping clearing
|
||||
as an explicit value avoids that coupling.
|
||||
|
||||
### OD-7. Which Lifecycle Stages Participate?
|
||||
|
||||
Do the new cross-tier operations extend only source-backed tiers, or also
|
||||
|
||||
Reference in New Issue
Block a user