Implement strict document composition
This commit is contained in:
@@ -802,7 +802,27 @@ Acceptance:
|
||||
|
||||
## Stage 10 — Implement strict document composition
|
||||
|
||||
Status: pending.
|
||||
Status: complete.
|
||||
|
||||
Completion evidence (2026-09-06):
|
||||
|
||||
- Adapted Narratio's additive claim validation and recursive mapping join into the
|
||||
private `composeDocuments` boundary over ConfigKit-owned document trees. Present
|
||||
equal or unequal scalars, nulls, sequences, mapping/value kind changes, and nested
|
||||
duplicate entries return `compose.conflict`; mapping pairs alone recurse.
|
||||
- Changed the extracted empty-map behavior to ConfigKit's operation table: empty
|
||||
mappings add no children, compose with other mappings, and retain their container
|
||||
location in composite base origins. Application defaults never enter the composer.
|
||||
- Preserved source/declaration traversal in detached ordered claim records and used
|
||||
it only for assembled order and exact primary/related diagnostics. Conflicts across
|
||||
three or more inputs report every claimant, while shared containers aggregate all
|
||||
contributing locations instead of selecting an arbitrary owner.
|
||||
- Cloned every retained branch and verified mutations of a composed result cannot
|
||||
affect any input. Focused tests cover disjoint keyed joins, operation categories,
|
||||
ancestor and nested conflicts, equal values, nulls, sequences, empty mappings,
|
||||
exact locations, all claimants, invalid boundaries, and nonmutation. The
|
||||
[current composition contract](../config.md#strict-document-composition) owns the
|
||||
implemented semantics; public import wiring remains deferred to subsequent work.
|
||||
|
||||
Read: feature [composition table](initial.md#composition-and-overlay).
|
||||
|
||||
|
||||
@@ -450,28 +450,24 @@ origin is a resolution operation, with input origins retained separately.
|
||||
|
||||
## Composition and overlay
|
||||
|
||||
Composition combines the main file and explicitly imported fragments as peers.
|
||||
Repeated semantic definitions are errors, even when their values are equal.
|
||||
Both conflicting locations must be reported. Prefer mappings keyed by stable
|
||||
identifiers when entries need to be contributed independently.
|
||||
Strict base composition is implemented and now owned by the
|
||||
[current configuration contract](../config.md#strict-document-composition).
|
||||
Intentional profile overlay remains target behavior. Its exhaustive operation table
|
||||
is below; “value” includes scalar, sequence, mapping, and null, while absent means no
|
||||
node rather than null.
|
||||
|
||||
The following table is exhaustive by node category. “Value” includes scalar,
|
||||
sequence, mapping, and null. Absent means no node, not null.
|
||||
| Existing/lower node | Incoming/higher node | Overlay |
|
||||
| --- | --- | --- |
|
||||
| Absent | Absent | Absent |
|
||||
| Absent | Value | Incoming |
|
||||
| Value | Absent | Existing |
|
||||
| Mapping | Mapping | Recurse by key |
|
||||
| Any other pair of present nodes | Any other pair of present nodes | Replace entire existing node |
|
||||
|
||||
| Existing/lower node | Incoming/higher node | Strict composition | Overlay |
|
||||
| --- | --- | --- | --- |
|
||||
| Absent | Absent | Absent | Absent |
|
||||
| Absent | Value | Incoming | Incoming |
|
||||
| Value | Absent | Existing | Existing |
|
||||
| Mapping | Mapping | Recurse by key | Recurse by key |
|
||||
| Any other pair of present nodes | Any other pair of present nodes | Collision | Replace entire existing node |
|
||||
|
||||
Two empty mappings compose successfully. An empty mapping contributes no child
|
||||
changes to an existing mapping; it does not clear that mapping. A mapping can
|
||||
replace a lower scalar, sequence, or null during overlay, subject to the final
|
||||
schema. Sequences are atomic: two definitions collide in composition and the
|
||||
higher sequence replaces the entire lower sequence in an overlay. `[]` clears a
|
||||
sequence. There is no append, union, index merge, or mapping-clear operator.
|
||||
A mapping can replace a lower scalar, sequence, or null during overlay, subject to
|
||||
the final schema. Sequences are atomic and the higher sequence replaces the entire
|
||||
lower sequence in an overlay. `[]` clears a sequence. There is no append, union,
|
||||
index merge, or mapping-clear operator.
|
||||
|
||||
Replacing a parent must not leave effective metadata for removed children.
|
||||
Sequence histories describe whole-sequence replacement; index origins refer to
|
||||
|
||||
Reference in New Issue
Block a user