Settle nested sequence policy ownership and record review findings

This commit is contained in:
2026-10-23 00:02:26 +00:00
parent 0e430e8077
commit 8a54cecd1d

View File

@@ -1,10 +1,9 @@
# Sequence Identity And Combination
Status: feature roadmap with OD-1 through OD-10 settled and follow-up interaction
decision OD-11 open. The original decisions establish the intended operations;
the remaining question addresses nested policy ownership and transfer.
Resolve it before preparing a staged implementation plan. This is
not an implementation plan or an implemented contract.
Status: feature roadmap with OD-1 through OD-11 settled. A whole-roadmap review
identified the remaining policy-lifetime clarification in OD-12 below. Resolve it
and review the completed roadmap before preparing a staged implementation plan.
This is not an implementation plan or an implemented contract.
## Motivation
@@ -116,7 +115,7 @@ relative to the declaring source's placement: a fragment mounted under
`catalog` can declare `[prompts]` locally. A sequence-item source can declare a
nested collection within its own item without referring to an eventual numeric
index. Preserve those source and item-local scope boundaries.
OD-11 addresses policy ownership when enclosing records are replaced or inherited.
OD-11 settles policy ownership when enclosing records are replaced or inherited.
Identity and mode can be supplied independently. Omitted identity can use an
application registration; an explicit matching declaration is accepted, and a
@@ -685,7 +684,12 @@ paths or supplied values. CLI overrides supply application values after structur
processing; they do not initiate a second inheritance pass. This deliberately
changes the current ability to supply or cancel `extends` through CLI input.
CLI changes cannot prevent an earlier inheritance failure or change which
relationships that completed pass resolved.
relationships that completed pass resolved. Likewise, because typed decoding
precedes CLI application, an invalid source value that fails decoding cannot be
repaired by a CLI replacement. For example, a string supplied for an integer
field fails before a valid integer override can apply. This differs from the
current override-before-decoding behavior. Semantic validation remains after
overrides and application resolution, as specified above.
This ordering supersedes the current CLI-before-inheritance lifecycle described
in [ADR 0009](../adr/0009-sibling-inheritance.md). It avoids special replacement
@@ -727,7 +731,8 @@ 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
ownership and transfer, including the distinction between surviving records and
inheritance copies. CLI overrides remain outside sequence mode selection
under OD-8. Strict peer composition and all ordering rules in OD-4 are unchanged.
### Lower-Tier Identity During Strict Composition
@@ -753,8 +758,11 @@ Determine applicability using OD-3's agreement and replacement rules: append and
upsert require agreement, while whole-sequence replacement may change or discard
YAML-only identity. A replacing collection must not be constrained by an obsolete
lower identity merely because policy resolution precedes strict composition.
Application registrations remain authoritative. Higher-tier declarations do not
retroactively repair invalid lower-tier composition.
Application registrations remain authoritative. Under OD-11, a replacement
record also cannot borrow item-local identity owned by the discarded lower
record, even if both records have the same outer identity or numeric position.
Higher-tier declarations do not retroactively repair invalid lower-tier
composition.
Separate source acquisition from policy-aware composition, or otherwise revise
assembly sequencing, so accumulated lower policy is available before higher-tier
@@ -766,6 +774,59 @@ main-version checks, and failure diagnostics when changing the handoffs. Retain
version ownership and validation semantics; do not use higher-tier replacement
to hide lower-tier structural failures.
### Nested Policy Ownership And Transfer
**OD-11: settled.**
Attach item-local collection policies to their owning contributions. Policies
follow surviving records independently of numeric indexes. Whole-record upsert
replacement discards the old record's local policies along with its fields;
whole-sequence replacement likewise discards policies owned by removed records.
A replacement record supplies its own local declarations. Sharing an outer
identity or occupying the same final index does not transfer the discarded
record's policies to its replacement.
For example, a source imported as one record into `prompts` can declare:
```yaml
configkit:
sequences:
- destination: [steps]
key: id
mode: append
id: foo
steps:
- id: prepare
```
The declaration governs `steps` inside that particular `foo` record. Retaining
`foo` retains its local policy, including its explicit mode under OD-9. Upserting
a new `foo` discards the old `steps` and its declaration; the replacement does not
inherit either merely because upsert retains the outer record's position.
Distinguish inherited collection identity from operation instructions. YAML
identity follows a collection copied through sibling inheritance, subject to
OD-3's agreement and replacement rules. The inheriting destination selects its
operation under OD-7 and OD-9; the source collection's mode does not automatically
become an instruction at the new destination.
For example, a source mapping's `steps` collection has `key: id` and
`mode: append`. An inheriting mapping supplies local `steps` but no applicable
explicit mode. The copied identity selects upsert at the inheriting destination;
the source's append mode remains applicable at its own destination. An explicit
append declaration at the inheriting destination instead selects append there.
A destination declaration of the same key agrees; a different key conflicts when
combining records, while explicit replacement can establish a new YAML identity
under OD-3.
Application registrations remain constraints at their registered destinations;
copying a collection does not create another application registration. Policies
that independently apply at the destination are not discarded merely because
an individual record is replaced. Ownership determines which declarations are
removed. This preserves OD-9's persistence rule for applicable explicit modes
without retaining declarations owned by discarded records. The implementation
plan should choose the bookkeeping needed to preserve these distinctions.
## Architectural Direction
The settled collection declaration gives imported and inline records at the same
@@ -812,30 +873,42 @@ Public API design and test sequencing belong to that later plan.
## Open Decisions
### OD-11. Nested Policy Ownership And Transfer
### OD-12. Identity Declarations Without Sequence Values
OD-2 allows collection declarations inside imported items, and OD-3 ties YAML-only
identity to surviving collections. Specify what happens to those policies when
an enclosing record is upserted, replaced, moved, or copied through inheritance.
For example, replacing record `foo` wholesale must account for the old record's
declaration governing `foo.steps`; keeping the numeric index alone does not
establish that the old policy still belongs there.
OD-9 defines a mode-only declaration without accompanying records. Clarify the
corresponding behavior for `key`, including a declaration made before any sequence
exists, and complete OD-3's identity-lifetime rule for non-sequence replacement.
These cases must have defined results before the implementation plan chooses how
to store collection policy.
**Recommendation:** Attach item-local policies to their owning contributions so
they follow surviving records independently of numeric indexes. Whole-record
replacement discards policies owned by the discarded record. Distinguish inherited
collection identity from operation instructions: copied identity may follow a
surviving collection, while the inheriting destination selects its operation under
OD-7. Application registrations remain constraints at their registered destinations.
Provide nested examples showing retained records, replaced records, inherited
copies, and agreement with declarations at the destination. This protects the
established whole-record replacement semantics and prevents stale policies from
attaching to unrelated records after reindexing.
For example, a lower tier supplies an unkeyed `prompts` sequence and a higher tier
only declares `destination: [prompts], key: id`. Does this validate and identify
the retained sequence immediately? Can a declaration in an otherwise empty
underlay establish identity for main-tier fragments under OD-10? Conversely, if
an identified sequence is replaced by null, does its old YAML identity disappear?
OD-6 specifies the resulting values but does not fully specify these policy effects.
**Alternative:** Keep configuration policies solely in a destination registry and
rebind them after structural changes. This offers centralized lookup, but numeric
paths cannot safely identify changing records, and item-local declarations still
need ownership information to distinguish policies that should survive from
policies whose declaring records were discarded. Requiring declarations again at
each inherited destination reduces transfer rules but makes reusable fragments
more repetitive and would narrow the current identity-follows-collection model.
**Recommendation:** Allow identity declarations without accompanying records.
Apply the declaration to a retained sequence immediately, checking identity
agreement and validating its records; do not recombine earlier tiers. If the
collection is absent, retain the declaration in its owning scope for later
contributions without requiring the collection to exist. Merely declaring replace
without supplying a replacement value does not authorize changing a retained
collection's identity. Extend OD-3's replacement rule to any actual replacement
of the collection by a non-sequence value: discard the lower YAML-only identity,
retain any identity explicitly declared by the replacing tier, and preserve
application constraints. An explicit declaration can remain pending at an absent
or non-sequence destination without independently imposing a shape requirement;
OD-6 still governs whether an attempted operation on a non-sequence value fails.
These rules allow baseline policy declarations while keeping identity removal
tied to actual replacement. Explicit mode persistence remains governed by OD-9.
**Alternative:** Require a YAML identity declaration to have a sequence in the
same tier. This keeps YAML identity attached only to concrete sequence values
and reduces pending-policy cases, but prevents policy-only baseline files and
requires authors to repeat declarations beside later contributions. It also
makes identity declarations less flexible than the settled mode declarations.
For non-sequence replacement, retaining the lower YAML identity until another
sequence appears is another viable choice; it supports persistent schema-like
policy, but conflicts with the current distinction between collection-owned
YAML identity and application-owned constraints and would require revisiting OD-3.