Settle sequence identity definitions and policy lifetime
This commit is contained in:
@@ -45,6 +45,8 @@ later. Extending one does not automatically imply extending the other.
|
|||||||
|
|
||||||
The proposed `configkit.sequences` block introduces a `key` declaration that
|
The proposed `configkit.sequences` block introduces a `key` declaration that
|
||||||
accepts either one field or a list of fields for a compound identity.
|
accepts either one field or a list of fields for a compound identity.
|
||||||
|
Fields are treated as a set; identity components may be strings, numbers,
|
||||||
|
booleans, or explicitly supplied null values.
|
||||||
Applications retain an optional interface for registering a collection
|
Applications retain an optional interface for registering a collection
|
||||||
and imposing its identity definition. Configuration declarations must conform
|
and imposing its identity definition. Configuration declarations must conform
|
||||||
to an application-owned constraint when one exists. The exact Go interface
|
to an application-owned constraint when one exists. The exact Go interface
|
||||||
@@ -116,13 +118,13 @@ Identity and mode can be supplied independently. Omitted identity can use an
|
|||||||
application registration; an explicit matching declaration is accepted, and a
|
application registration; an explicit matching declaration is accepted, and a
|
||||||
conflicting declaration is invalid. Whole-sequence replacement does not itself
|
conflicting declaration is invalid. Whole-sequence replacement does not itself
|
||||||
require identity matching, but application-owned constraints still apply.
|
require identity matching, but application-owned constraints still apply.
|
||||||
Identity-policy lifetime across tiers remains under OD-3.
|
Identity-policy lifetime across tiers is settled in OD-3 below.
|
||||||
|
|
||||||
Mode describes the current tier's combination instruction. A lower tier's
|
Mode describes the current tier's combination instruction. A lower tier's
|
||||||
`append` does not silently select append for a later overlay. Gather collection
|
`append` does not silently select append for a later overlay. Gather collection
|
||||||
declarations before composing their relevant scope so their effect does not
|
declarations before composing their relevant scope so their effect does not
|
||||||
depend on which contribution is assembled first. Agreement and omission among
|
depend on which contribution is assembled first. Identity agreement is settled
|
||||||
peer declarations remain under OD-4.
|
in OD-3; operation agreement and omission among peers remain under OD-4.
|
||||||
|
|
||||||
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
|
||||||
@@ -185,6 +187,90 @@ inline/imported collections without duplicate authoring surfaces. Local wrappers
|
|||||||
around sequence values would require distinguishing application data from
|
around sequence values would require distinguishing application data from
|
||||||
control mappings; the existing reserved namespace keeps that distinction clear.
|
control mappings; the existing reserved namespace keeps that distinction clear.
|
||||||
|
|
||||||
|
### Identity Definitions And Lifetime
|
||||||
|
|
||||||
|
**OD-3: settled.**
|
||||||
|
|
||||||
|
#### Field Sets
|
||||||
|
|
||||||
|
`key` accepts a string or a nonempty list of strings naming direct, literal
|
||||||
|
fields in each record. `key: id` and `key: [id]` are equivalent. A name such as
|
||||||
|
`metadata.id` denotes that literal field, not a nested lookup.
|
||||||
|
|
||||||
|
Treat the selected fields as a set: remove repeated names and disregard authored
|
||||||
|
field order when comparing definitions. For example, `[namespace, id]`,
|
||||||
|
`[id, namespace]`, and `[namespace, id, id]` define the same identity. An empty
|
||||||
|
list is invalid because it supplies no identity fields. These equivalence rules
|
||||||
|
also apply when comparing configuration declarations with application
|
||||||
|
registrations.
|
||||||
|
|
||||||
|
Use a consistent field order internally to construct compound identity tuples.
|
||||||
|
Preserve component types and tuple boundaries; concatenating unstructured values
|
||||||
|
must not cause otherwise distinct identities to collide.
|
||||||
|
|
||||||
|
#### Scalar Components And Equality
|
||||||
|
|
||||||
|
Each identified record must be a mapping, and every designated identity field
|
||||||
|
must be present. Components may be strings, numbers, booleans, or explicit null.
|
||||||
|
Missing fields and mapping or sequence components are invalid. A present null is
|
||||||
|
a valid component and is distinct from an absent field. Two single-field null
|
||||||
|
identities are equal; in a compound identity, all components must compare equal.
|
||||||
|
|
||||||
|
Strings compare exactly, with no trimming, case folding, or normalization.
|
||||||
|
Empty strings remain valid. Scalar categories remain distinct: the string
|
||||||
|
`"1"`, the number `1`, the boolean `true`, and null are different identities.
|
||||||
|
|
||||||
|
Numbers compare by mathematical value across integer, fractional, and exponent
|
||||||
|
spellings: `1`, `1.0`, and `1e0` are equal, as are `0` and `-0`. Use exact numeric
|
||||||
|
normalization for identity comparison without rounding through a floating-point
|
||||||
|
conversion. This comparison does not rewrite authored values or alter existing
|
||||||
|
typed decoding and projection semantics. The existing parser's rejection of
|
||||||
|
non-finite numeric forms remains unchanged.
|
||||||
|
|
||||||
|
#### Agreement And Introduction
|
||||||
|
|
||||||
|
Within a strict tier, identity declarations for the same collection must agree.
|
||||||
|
Equivalent field sets coalesce; different sets produce an error. Across tiers,
|
||||||
|
append and replacement by identity use one agreed definition for the records
|
||||||
|
being combined:
|
||||||
|
|
||||||
|
| Lower collection identity | Higher declaration | Result when combining records |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `id` | Omitted | Use `id` |
|
||||||
|
| `id` | `id`, `[id]`, or `[id, id]` | Accept the equivalent definition |
|
||||||
|
| `id` | `[namespace, id]` | Error: different identity definitions |
|
||||||
|
| None | `id` | Establish `id` and validate all participating records under it |
|
||||||
|
|
||||||
|
An application registration supplies identity when configuration omits it and
|
||||||
|
remains authoritative over explicit declarations. If neither the application nor
|
||||||
|
either participating collection supplies an identity, append and replacement by
|
||||||
|
identity fail; ConfigKit does not infer an `id` convention. Introducing identity
|
||||||
|
for a previously unkeyed lower sequence requires checking both lower and incoming
|
||||||
|
records, including uniqueness within each contribution.
|
||||||
|
|
||||||
|
#### Replacement And Policy Lifetime
|
||||||
|
|
||||||
|
YAML-owned identity follows the collection that survives an operation:
|
||||||
|
|
||||||
|
| Operation | Effective YAML-owned identity |
|
||||||
|
| --- | --- |
|
||||||
|
| Append | Retain or establish the agreed identity |
|
||||||
|
| Replacement by identity | Retain or establish the agreed identity |
|
||||||
|
| Whole-sequence replacement | Use the replacing tier's declaration and discard the lower collection's YAML-only identity |
|
||||||
|
|
||||||
|
Without an application constraint, whole-sequence replacement may introduce a
|
||||||
|
different identity, such as replacing an `id`-keyed collection with a `name`-keyed
|
||||||
|
collection. A whole-sequence replacement with no new identity declaration and no
|
||||||
|
application registration produces an unkeyed sequence. No separate identity
|
||||||
|
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.
|
||||||
|
|
||||||
### Whole-Record Replacement By Identity
|
### Whole-Record Replacement By Identity
|
||||||
|
|
||||||
The third cross-tier operation replaces each matching lower record with the
|
The third cross-tier operation replaces each matching lower record with the
|
||||||
@@ -264,9 +350,9 @@ and does not extend to caller mutations after loading returns.
|
|||||||
|
|
||||||
Keep the promise limited to the declared identity constraints. It does not by
|
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
|
itself require registered paths to exist or settle null and non-sequence
|
||||||
handling; those boundaries remain under OD-3 and OD-6. Final validation examines
|
handling; those collection boundaries remain under OD-6. Final validation examines
|
||||||
effective typed values, while assembly-time checks retain their role in
|
effective typed values, while assembly-time checks retain their role in
|
||||||
validating authored contributions. A final string value alone does not prove
|
validating authored contributions. A final scalar value alone does not prove
|
||||||
that the field was explicitly supplied in a source.
|
that the field was explicitly supplied in a source.
|
||||||
|
|
||||||
The existing canonical final-value representation and shared publication path
|
The existing canonical final-value representation and shared publication path
|
||||||
@@ -286,16 +372,17 @@ The initial recommendation is to compose each tier's contributions strictly,
|
|||||||
then apply one collection operation from the higher tier against the lower
|
then apply one collection operation from the higher tier against the lower
|
||||||
sequence. A collection declaration would therefore govern its tier's contribution
|
sequence. A collection declaration would therefore govern its tier's contribution
|
||||||
at that destination, without sequentially erasing peer contributions. Multiple
|
at that destination, without sequentially erasing peer contributions. Multiple
|
||||||
agreeing declarations could coalesce; conflicting explicit identity or operation
|
agreeing operation declarations could coalesce; conflicting explicit operations
|
||||||
declarations would produce errors.
|
would produce errors. Identity declaration agreement is already settled in OD-3.
|
||||||
|
|
||||||
For append, the ordering recommendation is to retain lower-tier item order and
|
For append, the ordering recommendation is to retain lower-tier item order and
|
||||||
then the higher tier's assembled item order. For replacement by identity, retain
|
then the higher tier's assembled item order. For replacement by identity, retain
|
||||||
the position of each replaced record and append new identities in higher-tier
|
the position of each replaced record and append new identities in higher-tier
|
||||||
order. Existing dependency-ready scheduling would continue to determine assembly
|
order. Existing dependency-ready scheduling would continue to determine assembly
|
||||||
order within a tier. Whole-sequence replacement would retain only the higher
|
order within a tier. Whole-sequence replacement would retain only the higher
|
||||||
tier's assembled sequence. Ordering and the treatment of peer declarations remain
|
tier's assembled sequence. Ordering and the treatment of peer operation
|
||||||
recommendations awaiting agreement, not changes to the current ordering contract.
|
declarations remain recommendations awaiting agreement, not changes to the
|
||||||
|
current ordering contract.
|
||||||
|
|
||||||
This requires collection policy to survive import expansion through precedence
|
This requires collection policy to survive import expansion through precedence
|
||||||
assembly. Correctness includes final values, projected item paths, source
|
assembly. Correctness includes final values, projected item paths, source
|
||||||
@@ -333,37 +420,17 @@ Application-registered collections have the settled final-result guarantee
|
|||||||
above. Should a configuration-only identity declaration carry the same
|
above. Should a configuration-only identity declaration carry the same
|
||||||
guarantee, or govern structural assembly alone?
|
guarantee, or govern structural assembly alone?
|
||||||
|
|
||||||
**Initial recommendation:** With declaration scope settled in OD-2, resolve
|
**Discussion basis:** Declaration scope and identity-policy lifetime are settled
|
||||||
identity-policy lifetime across replacement in OD-3 before this choice. Final
|
in OD-2 and OD-3. Revisit final enforcement using the effective identity of each
|
||||||
enforcement needs an unambiguous effective policy for each retained collection. The
|
retained collection. The application-owned guarantee remains independent of
|
||||||
application-owned guarantee can proceed independently of this choice.
|
this choice.
|
||||||
|
|
||||||
**Alternatives:** Applying the same final check to YAML-declared identities
|
**Alternatives:** Applying the same final check to YAML-declared identities
|
||||||
would give both declaration forms consistent enforcement, but requires resolving
|
would give both declaration forms consistent enforcement, but requires carrying
|
||||||
which policy survives replacement or follows nested records. Limiting YAML-only
|
the effective policy through later lifecycle stages, including nested records.
|
||||||
identity to assembly keeps policy lifetime narrower, but later operations could
|
Limiting YAML-only identity to assembly keeps policy lifetime narrower, but later
|
||||||
produce a final collection that no longer satisfies that identity declaration.
|
operations could produce a final collection that no longer satisfies that
|
||||||
|
identity declaration.
|
||||||
### OD-3. What Constitutes Identity, And When Can It Change?
|
|
||||||
|
|
||||||
Settle compound-key field selection, value types, missing/null components,
|
|
||||||
empty and repeated field lists, empty identity strings, and agreement between
|
|
||||||
declarations. Decide whether whole-sequence replacement can introduce a different identity
|
|
||||||
definition after discarding the lower collection when the application has imposed
|
|
||||||
no identity constraint. An application-owned constraint remains authoritative.
|
|
||||||
|
|
||||||
**Initial recommendation:** Interpret `key: id` as `[id]` and a compound key as
|
|
||||||
an ordered tuple of direct, literal string fields. Retain exact string comparison
|
|
||||||
and require every component to be present. Preserve tuple boundaries rather than
|
|
||||||
concatenating values. Identity declarations participating in append or replacement
|
|
||||||
by identity must agree; equal definitions within a scope coalesce and conflicting
|
|
||||||
definitions fail. Detailed list validation and identity changes at whole-sequence
|
|
||||||
replacement boundaries remain to be settled.
|
|
||||||
|
|
||||||
**Alternative:** Permit additional scalar types or nested field paths. These
|
|
||||||
support more schemas but add type-equality and addressing rules. A load-wide fixed
|
|
||||||
identity definition simplifies agreement across tiers; allowing a replacement to
|
|
||||||
establish a new definition gives independently authored layers more flexibility.
|
|
||||||
|
|
||||||
### OD-4. What Does A Combination Choice Control?
|
### OD-4. What Does A Combination Choice Control?
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user