Settle persistent sequence operation policy
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
# Sequence Identity And Combination
|
# Sequence Identity And Combination
|
||||||
|
|
||||||
Status: feature roadmap with OD-1 through OD-8 settled and follow-up interaction
|
Status: feature roadmap with OD-1 through OD-9 settled and follow-up interaction
|
||||||
decisions OD-9 through OD-11 open. The original decisions establish the intended
|
decisions OD-10 and OD-11 open. The original decisions establish the intended
|
||||||
operations; the new questions address their lifecycle and policy-scope boundaries.
|
operations; the new questions address their lifecycle and policy-scope boundaries.
|
||||||
Resolve these questions before preparing a staged implementation plan. This is
|
Resolve these questions before preparing a staged implementation plan. This is
|
||||||
not an implementation plan or an implemented contract.
|
not an implementation plan or an implemented contract.
|
||||||
@@ -125,12 +125,12 @@ require identity matching, but application-owned constraints still apply.
|
|||||||
Identity-policy lifetime across tiers is settled in OD-3 below.
|
Identity-policy lifetime across tiers is settled in OD-3 below.
|
||||||
|
|
||||||
Mode describes the collection's combination instruction at source-precedence
|
Mode describes the collection's combination instruction at source-precedence
|
||||||
and inheritance boundaries, as detailed in OD-7. A lower tier's
|
and inheritance boundaries, as detailed in OD-7. An explicit mode persists at
|
||||||
`append` does not silently select append for a later overlay. Gather collection
|
the same applicable destination until a higher-tier declaration changes it.
|
||||||
declarations before composing their relevant scope so their effect does not
|
Gather collection declarations before composing their relevant scope so their
|
||||||
depend on which contribution is assembled first. Identity agreement is settled
|
effect does not depend on which contribution is assembled first. Identity agreement is settled
|
||||||
in OD-3; operation agreement and omission among peers are settled in OD-4.
|
in OD-3; operation agreement and omission among peers are settled in OD-4.
|
||||||
OD-9 addresses which controls survive source precedence for later inheritance.
|
OD-9 settles how operation controls survive source precedence for later inheritance.
|
||||||
|
|
||||||
Permit sequence declarations in selected overlays and make their use independent
|
Permit sequence declarations in selected overlays and make their use independent
|
||||||
of filesystem import enablement. This deliberately changes the current blanket
|
of filesystem import enablement. This deliberately changes the current blanket
|
||||||
@@ -152,8 +152,9 @@ prompts:
|
|||||||
text: Revised definition
|
text: Revised definition
|
||||||
```
|
```
|
||||||
|
|
||||||
The explicit `mode: upsert` line can be omitted here because `key: id` supplies
|
The explicit `mode: upsert` line can be omitted here when no different explicit
|
||||||
an effective identity. An overlay can instead select duplicate-rejecting append:
|
mode applies from a lower tier: `key: id` then supplies the identity for inferred
|
||||||
|
upsert. An overlay can instead select duplicate-rejecting append:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
configkit:
|
configkit:
|
||||||
@@ -182,11 +183,12 @@ prompts:
|
|||||||
text: Baz definition
|
text: Baz definition
|
||||||
```
|
```
|
||||||
|
|
||||||
Explicitly selecting the default operation is valid. Removing the last example's
|
Explicitly selecting the default operation is valid. With no applicable explicit
|
||||||
`configkit` block produces the same replacement behavior only when no effective
|
mode, removing the last example's `configkit` block selects replace only when no
|
||||||
identity is available. For an identified collection, explicit `mode: replace`
|
effective identity is available; an identified collection instead selects upsert.
|
||||||
overrides the inferred `upsert`; it is not redundant. OD-5 defines the selection
|
A retained explicit mode also affects omission. Explicit `mode: replace` overrides
|
||||||
rule for `replace`, `append`, and `upsert`.
|
either another retained mode or inferred upsert. OD-5 defines the selection rule
|
||||||
|
for `replace`, `append`, and `upsert`.
|
||||||
|
|
||||||
Start with this common collection declaration and defer `key` and `mode`
|
Start with this common collection declaration and defer `key` and `mode`
|
||||||
shorthand on imports. A single declaration form covers inline overlays and mixed
|
shorthand on imports. A single declaration form covers inline overlays and mixed
|
||||||
@@ -306,7 +308,8 @@ The tier operation does not sequentially replace peer source contributions.
|
|||||||
|
|
||||||
Coalesce agreeing explicit modes for the same collection within a tier and
|
Coalesce agreeing explicit modes for the same collection within a tier and
|
||||||
reject conflicting explicit modes. Omission expresses no preference; apply the
|
reject conflicting explicit modes. Omission expresses no preference; apply the
|
||||||
default only after reconciling declarations.
|
effective-identity default only after reconciling declarations and checking for
|
||||||
|
an applicable explicit mode retained from a lower tier.
|
||||||
|
|
||||||
| Modes declared within one tier | Effective operation |
|
| Modes declared within one tier | Effective operation |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
@@ -314,12 +317,13 @@ default only after reconciling declarations.
|
|||||||
| `append` and omitted | `append` |
|
| `append` and omitted | `append` |
|
||||||
| `replace` and omitted | `replace` |
|
| `replace` and omitted | `replace` |
|
||||||
| `append` and `replace` | Error |
|
| `append` and `replace` | Error |
|
||||||
| All omitted | `upsert` with effective identity; otherwise `replace` |
|
| All omitted | Retain an applicable lower explicit mode; otherwise infer from effective identity |
|
||||||
|
|
||||||
Explicitly selecting the default is a real instruction and can conflict with
|
Explicitly selecting the default is a real instruction and can conflict with
|
||||||
another explicit selection. Different modes in different tiers are valid; a
|
another explicit selection. Different modes in different tiers are valid; the
|
||||||
lower tier's mode does not carry forward. Neither a root declaration nor a later
|
higher tier's explicit mode replaces the lower mode, while omission retains it.
|
||||||
declaration wins over conflicting peers. Diagnostics identify the collection
|
Neither a root declaration nor a later declaration wins over conflicting peers.
|
||||||
|
Diagnostics identify the collection
|
||||||
destination and conflicting declaration locations. OD-5 defines mode names and
|
destination and conflicting declaration locations. OD-5 defines mode names and
|
||||||
the default-selection rule.
|
the default-selection rule.
|
||||||
|
|
||||||
@@ -376,21 +380,25 @@ Select the operation at each collection's precedence boundary in this order:
|
|||||||
|
|
||||||
1. Reconcile explicit modes within the current tier under OD-4; conflicting
|
1. Reconcile explicit modes within the current tier under OD-4; conflicting
|
||||||
explicit modes fail.
|
explicit modes fail.
|
||||||
2. If an explicit mode is supplied, use it.
|
2. If the current tier supplies an explicit mode, use it in place of a lower mode.
|
||||||
3. Otherwise, select `upsert` when an effective identity is available.
|
3. Otherwise, retain an applicable explicit mode from a lower tier.
|
||||||
4. Otherwise, select `replace`.
|
4. If no explicit mode applies, select `upsert` when effective identity is available.
|
||||||
|
5. Otherwise, select `replace`.
|
||||||
|
|
||||||
Effective identity may come from an application registration, a current-tier
|
Effective identity may come from an application registration, a current-tier
|
||||||
declaration, or the lower collection, subject to OD-3's agreement rules.
|
declaration, or the lower collection, subject to OD-3's agreement rules.
|
||||||
Selection depends on identity availability, not on whether the current tier
|
Selection depends on identity availability, not on whether the current tier
|
||||||
explicitly repeats a `key` declaration. A plain overlay sequence can therefore
|
explicitly repeats a `key` declaration. With no applicable explicit mode, a plain
|
||||||
default to `upsert` when identity was established elsewhere. A lower tier's mode
|
overlay sequence can therefore default to `upsert` when identity was established
|
||||||
does not carry forward.
|
elsewhere. New sequence values do not reset an existing explicit mode. Inferred
|
||||||
|
defaults do not become persistent explicit instructions: when no explicit mode
|
||||||
|
applies, determine the default from the identity available at that boundary.
|
||||||
|
|
||||||
Determine the inferred mode using the available identity before applying the
|
Determine the inferred mode using the available identity before applying the
|
||||||
operation. Explicit `replace` still follows OD-3: discard the lower collection's
|
operation. `replace`, including a retained explicit mode, follows OD-3: discard
|
||||||
YAML-only identity with the lower sequence, use the replacing tier's identity
|
the lower collection's YAML-only identity with the lower sequence, use the
|
||||||
declaration if supplied, and preserve application-owned constraints. Selecting
|
replacing tier's identity declaration if supplied, and preserve application-owned
|
||||||
|
constraints. Selecting
|
||||||
`append` or `upsert` explicitly still requires an effective identity.
|
`append` or `upsert` explicitly still requires an effective identity.
|
||||||
|
|
||||||
This default governs combination between tiers and during sibling inheritance
|
This default governs combination between tiers and during sibling inheritance
|
||||||
@@ -525,10 +533,11 @@ non-sequence lower value is distinct from absence: append and upsert against it
|
|||||||
fail, while replacement remains available. An empty incoming sequence does not
|
fail, while replacement remains available. An empty incoming sequence does not
|
||||||
bypass these kind checks or the operation's identity requirements.
|
bypass these kind checks or the operation's identity requirements.
|
||||||
|
|
||||||
With effective identity available, an omitted mode selects upsert. Consequently,
|
With effective identity available and no applicable explicit mode, omission
|
||||||
`prompts: []` alone does not clear an identified collection. Clearing it requires
|
selects upsert. Consequently, `prompts: []` alone does not clear such a collection.
|
||||||
explicit `mode: replace`. Replacing an identified collection with null likewise
|
Clearing it requires replace, selected explicitly in the current tier or retained
|
||||||
requires explicit replacement and an application schema that permits null.
|
from a lower declaration. Replacing an identified collection with null likewise
|
||||||
|
requires replacement and an application schema that permits null.
|
||||||
|
|
||||||
An application identity registration does not itself require the collection path
|
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.
|
to exist or be non-null, and does not independently reject non-sequence values.
|
||||||
@@ -551,8 +560,9 @@ Complete source-tier assembly before resolving inheritance, retaining the
|
|||||||
existing dependency-ready inheritance algorithm and scope rules. At each
|
existing dependency-ready inheritance algorithm and scope rules. At each
|
||||||
inheritance combination, the resolved parent's collection is the lower value
|
inheritance combination, the resolved parent's collection is the lower value
|
||||||
and the inheriting mapping's local collection is the higher value. Use the same
|
and the inheriting mapping's local collection is the higher value. Use the same
|
||||||
operation selection as source precedence: an explicit mode wins; otherwise use
|
operation selection as source precedence: the effective explicit mode wins,
|
||||||
`upsert` with effective identity and `replace` without it. There is no separate
|
including one retained under OD-9; otherwise use `upsert` with effective identity
|
||||||
|
and `replace` without it. There is no separate
|
||||||
default-append rule for inheritance.
|
default-append rule for inheritance.
|
||||||
|
|
||||||
Use the inheriting destination collection's controls. Its selected mode governs
|
Use the inheriting destination collection's controls. Its selected mode governs
|
||||||
@@ -681,6 +691,44 @@ in [ADR 0009](../adr/0009-sibling-inheritance.md). It avoids special replacement
|
|||||||
markers carried through inheritance. Current contracts remain the implemented
|
markers carried through inheritance. Current contracts remain the implemented
|
||||||
baseline until the architectural and implementation work lands.
|
baseline until the architectural and implementation work lands.
|
||||||
|
|
||||||
|
### Persistent Operation Policy
|
||||||
|
|
||||||
|
**OD-9: settled; this revises the earlier tier-local mode rule in OD-4 and OD-5.**
|
||||||
|
|
||||||
|
An explicit mode is collection policy that persists at its applicable destination
|
||||||
|
until a higher-priority declaration changes it. Reconcile peers strictly within
|
||||||
|
each tier, then let a higher explicit mode replace a lower one. Omission retains
|
||||||
|
an applicable explicit mode regardless of whether the higher tier supplies new
|
||||||
|
sequence values. Source precedence and subsequent inheritance use the same
|
||||||
|
effective operation policy.
|
||||||
|
|
||||||
|
| Lower explicit mode | Higher declaration | Effective mode |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `append` | Mode omitted | `append` |
|
||||||
|
| `append` | `upsert` | `upsert` |
|
||||||
|
| `upsert` | `replace` | `replace` |
|
||||||
|
| None | Mode omitted, effective identity available | Inferred `upsert` |
|
||||||
|
| None | Mode omitted, no effective identity | Inferred `replace` |
|
||||||
|
|
||||||
|
An unrelated overlay leaves the policy intact. A mode-only declaration may change
|
||||||
|
the policy without supplying records; it neither clears the collection nor
|
||||||
|
retroactively recombines earlier tiers. A later source contribution or inheritance
|
||||||
|
operation uses the resulting policy. Supplying values alone does not reset it.
|
||||||
|
|
||||||
|
Only explicit modes persist. Inferred defaults are recomputed from effective
|
||||||
|
identity when needed. Thus explicitly selecting replace for an identified
|
||||||
|
collection continues to select replace in subsequent tiers until another mode is
|
||||||
|
declared; an author wanting upsert afterward must select it explicitly. Identity
|
||||||
|
availability and constraints still follow OD-3, including YAML-only identity
|
||||||
|
removal on whole-sequence replacement. Persisting a mode does not preserve an
|
||||||
|
identity that OD-3 discards.
|
||||||
|
|
||||||
|
This persistence is scoped to the applicable collection. It does not transfer a
|
||||||
|
parent mapping's mode automatically to another destination through `extends` or
|
||||||
|
resurrect policies owned by discarded records. OD-11 addresses nested policy
|
||||||
|
ownership and transfer. CLI overrides remain outside sequence mode selection
|
||||||
|
under OD-8. Strict peer composition and all ordering rules in OD-4 are unchanged.
|
||||||
|
|
||||||
## Architectural Direction
|
## Architectural Direction
|
||||||
|
|
||||||
The settled collection declaration gives imported and inline records at the same
|
The settled collection declaration gives imported and inline records at the same
|
||||||
@@ -725,35 +773,6 @@ Public API design and test sequencing belong to that later plan.
|
|||||||
|
|
||||||
## Open Decisions
|
## Open Decisions
|
||||||
|
|
||||||
### OD-9. Which Controls Survive Until Inheritance?
|
|
||||||
|
|
||||||
OD-4 prevents a lower tier's mode from selecting a later tier's operation, while
|
|
||||||
OD-7 retains destination controls for inheritance after source assembly. The
|
|
||||||
roadmap needs an explicit rule for a collection left untouched by a higher tier,
|
|
||||||
a newly supplied sequence with no mode, and declarations supplied without values.
|
|
||||||
For example, does an unrelated selected overlay erase a main source's explicit
|
|
||||||
replace instruction for a collection that later inherits records?
|
|
||||||
|
|
||||||
**Recommendation:** Distinguish untouched collections from new contributions.
|
|
||||||
Retain relevant controls for an untouched collection's later inheritance. When
|
|
||||||
a higher tier supplies a new sequence contribution, select its operation from
|
|
||||||
that tier's declarations and the effective-identity default; do not reuse the
|
|
||||||
lower mode. Permit a declaration without a sequence value to control later
|
|
||||||
inheritance without clearing the collection. Express these cases in a policy
|
|
||||||
lifetime table covering absent values, key-only and mode-only declarations,
|
|
||||||
explicit operations, and replacement of a collection or an enclosing subtree.
|
|
||||||
Identity changes must still satisfy OD-3.
|
|
||||||
|
|
||||||
This preserves intentional inheritance controls across unrelated overlays while
|
|
||||||
keeping each new sequence contribution's precedence operation local to its tier.
|
|
||||||
|
|
||||||
**Alternative:** Maintain a destination policy independently of value survival,
|
|
||||||
letting higher explicit policy fields override lower ones and omissions inherit
|
|
||||||
them. This makes declaration-only configuration straightforward, but modes can
|
|
||||||
become sticky when new values arrive. Applying that policy only to inheritance
|
|
||||||
would preserve OD-4 at the cost of two distinct policy-resolution rules; applying
|
|
||||||
it to source precedence would require revisiting OD-4.
|
|
||||||
|
|
||||||
### OD-10. Identity Availability During Strict Tier Composition
|
### OD-10. Identity Availability During Strict Tier Composition
|
||||||
|
|
||||||
Suppose an underlay declares `key: id`, while two main-tier fragments contribute
|
Suppose an underlay declares `key: id`, while two main-tier fragments contribute
|
||||||
|
|||||||
Reference in New Issue
Block a user