Implement strict document composition

This commit is contained in:
2026-09-06 20:26:57 +00:00
parent a0cd0977ee
commit 3257b2124c
8 changed files with 438 additions and 21 deletions

View File

@@ -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).

View File

@@ -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