Reconcile sequence identity documentation
This commit is contained in:
26
README.md
26
README.md
@@ -27,12 +27,14 @@ the [configuration contract](docs/config.md#effective-configuration-diffs) and
|
|||||||
[consumer guide](docs/consumers/README.md#effective-configuration-diffs) describe
|
[consumer guide](docs/consumers/README.md#effective-configuration-diffs) describe
|
||||||
its safe changed-region records and maintained workflows.
|
its safe changed-region records and maintained workflows.
|
||||||
|
|
||||||
Sources can also be explicitly placed as sequence items, and definitions can
|
Sources can also be explicitly placed as sequence items. Configuration
|
||||||
register selected sequences to append records with distinct string IDs during
|
declarations and application registrations can give selected sequences scalar
|
||||||
strict composition. Higher-priority sequences still replace lower-priority
|
identities and choose how they combine across precedence and inheritance.
|
||||||
sequences as whole values. See the [sequence contract](docs/config.md#strict-document-composition),
|
Strict peers combine distinct records, while higher-priority collections can
|
||||||
[maintained prompt example](docs/consumers/README.md#identified-prompt-sequences),
|
replace, append, or upsert whole records. See the
|
||||||
and [ADR 0014](docs/adr/0014-sequence-placement-and-composition.md).
|
[sequence contract](docs/config.md#strict-document-composition),
|
||||||
|
[maintained catalog examples](docs/consumers/README.md#identified-prompt-sequences),
|
||||||
|
and [ADR 0017](docs/adr/0017-collection-sequence-policy.md).
|
||||||
|
|
||||||
Imports are also explicit: a source may name files, search declared directories,
|
Imports are also explicit: a source may name files, search declared directories,
|
||||||
or select files with path globs. Applications can set load-wide import defaults
|
or select files with path globs. Applications can set load-wide import defaults
|
||||||
@@ -78,12 +80,12 @@ precedence tiers, mappings combine recursively, retaining omitted lower-priority
|
|||||||
children; other values replace lower-priority values. The main document and its
|
children; other values replace lower-priority values. The main document and its
|
||||||
imports form one strictly composed tier. Explicit underlay groups sit below it
|
imports form one strictly composed tier. Explicit underlay groups sit below it
|
||||||
and above typed defaults; a selected overlay applies before inheritance, while
|
and above typed defaults; a selected overlay applies before inheritance, while
|
||||||
explicit CLI overrides apply to the decoded configuration before application
|
explicit CLI overrides apply after decoding and before application resolution.
|
||||||
resolution. The [configuration contract](docs/config.md#strict-document-composition)
|
The [configuration contract](docs/config.md#strict-document-composition) owns
|
||||||
owns the detailed combination rules and input-specific constraints. At
|
the detailed combination rules and input-specific constraints. Declared or
|
||||||
definition-registered paths only, strict composition can append records with
|
registered collections combine distinct identified records within strict tiers
|
||||||
distinct explicit IDs; ordinary and unregistered sequences keep their conflict
|
and use their selected operation at precedence boundaries; other sequences keep
|
||||||
or whole-value replacement behavior.
|
their strict-conflict and whole-value-replacement behavior.
|
||||||
|
|
||||||
The [architecture goals](docs/policy/architecture.md#success-criteria) explain
|
The [architecture goals](docs/policy/architecture.md#success-criteria) explain
|
||||||
these priorities and how genuine new needs can justify extending the shared
|
these priorities and how genuine new needs can justify extending the shared
|
||||||
|
|||||||
@@ -138,6 +138,6 @@ Record inheritance also requires parent lookup by identity and checking for
|
|||||||
missing parents and cycles. Copied settings retain the same source, history,
|
missing parents and cycles. Copied settings retain the same source, history,
|
||||||
and sensitivity information as mapping-sibling inheritance.
|
and sensitivity information as mapping-sibling inheritance.
|
||||||
|
|
||||||
The configuration contract will define declaration syntax, identity comparison,
|
The [configuration contract](../config.md#strict-document-composition) defines
|
||||||
omission and empty-value behavior, and diagnostics when the feature is
|
declaration syntax, identity comparison, omission and empty-value behavior, and
|
||||||
implemented.
|
diagnostics for the implemented feature.
|
||||||
|
|||||||
@@ -80,5 +80,5 @@ must remain consistent throughout loading.
|
|||||||
CLI input can no longer add or cancel inheritance relationships or bypass an
|
CLI input can no longer add or cancel inheritance relationships or bypass an
|
||||||
earlier error in source assembly or inheritance. It also cannot fix a value that
|
earlier error in source assembly or inheritance. It also cannot fix a value that
|
||||||
fails the earlier decoding step. Semantic validation still runs after overrides
|
fails the earlier decoding step. Semantic validation still runs after overrides
|
||||||
and application resolution. The configuration contract and consumer guidance
|
and application resolution. The [configuration contract](../config.md#explicit-cli-overrides)
|
||||||
must explain these behavior changes when they are implemented.
|
and [consumer guidance](../consumers/README.md) describe this behavior.
|
||||||
|
|||||||
199
docs/config.md
199
docs/config.md
@@ -814,9 +814,10 @@ validated, but there are no imported peers to combine.
|
|||||||
| Any other pair of present nodes | Any other pair of present nodes | `compose.conflict` |
|
| Any other pair of present nodes | Any other pair of present nodes | `compose.conflict` |
|
||||||
|
|
||||||
Every non-mapping overlap is a conflict, even when values are equal, except for
|
Every non-mapping overlap is a conflict, even when values are equal, except for
|
||||||
sequence/sequence contributions at a registered sequence identity destination
|
sequence/sequence contributions at a destination with effective identity from an
|
||||||
or a source-declared collection destination. Nulls remain atomic conflicts.
|
application registration, a current YAML `key` declaration, or retained lower
|
||||||
Unregistered and undeclared sequences conflict when repeated and are never joined
|
policy. Nulls remain atomic conflicts.
|
||||||
|
Sequences without effective identity conflict when repeated and are never joined
|
||||||
by index. Disjoint entries under shared mappings compose, making stable keyed
|
by index. Disjoint entries under shared mappings compose, making stable keyed
|
||||||
mappings the natural representation for independently contributed entries.
|
mappings the natural representation for independently contributed entries.
|
||||||
|
|
||||||
@@ -827,44 +828,49 @@ segments created by `SequenceLiteralKey` and `SequenceAnyMappingKey`. A literal
|
|||||||
`"*"` key is distinct from the wildcard constructor. Parsed numeric path tokens
|
`"*"` key is distinct from the wildcard constructor. Parsed numeric path tokens
|
||||||
remain literal mapping keys; explicit index segments and reserved `configkit` or
|
remain literal mapping keys; explicit index segments and reserved `configkit` or
|
||||||
mapping-valued `extends` segments are invalid. The root selector is harmless under
|
mapping-valued `extends` segments are invalid. The root selector is harmless under
|
||||||
the mapping-root schema. Each registration requires one or more literal field
|
the mapping-root schema. Selector segments consume one mapping level and match a
|
||||||
names; compound field sets are normalized as sets, and field names are not
|
complete destination; an any-mapping-key segment matches exactly one key, not an
|
||||||
otherwise normalized.
|
arbitrary prefix or suffix. Each registration requires one or more literal,
|
||||||
|
direct field names; compound field sets are normalized as sets, and field names
|
||||||
|
are not otherwise normalized. The same field-set and scalar-equality rules apply
|
||||||
|
to YAML `key` declarations.
|
||||||
|
|
||||||
At each selected path, records must provide every registered field as a scalar
|
At each selected path, records must provide every effective identity field as a
|
||||||
string, number, boolean, or explicit null. The type-tagged tuple preserves
|
scalar string, number, boolean, or explicit null. Field names form a set, so
|
||||||
category distinctions, while equivalent finite decimal spellings such as `1`,
|
order and repetition do not affect compound identity. The type-tagged tuple
|
||||||
`1.0`, and `1e0` compare as the same number. Distinct tuples append in source and
|
preserves category distinctions: strings compare exactly, including empty
|
||||||
list order; duplicate tuples conflict even when records are otherwise equal or
|
strings; numbers, booleans, and null remain distinct categories. Finite numbers
|
||||||
disjoint. Malformed records produce `compose.invalid`; duplicate identities
|
compare by exact mathematical value, so `1`, `1.0`, and `1e0` are equal, as are
|
||||||
|
`0` and `-0`, without floating-point rounding. Distinct tuples append in source
|
||||||
|
and list order; duplicate tuples conflict even when records are otherwise equal
|
||||||
|
or disjoint. Malformed records produce `compose.invalid`; duplicate identities
|
||||||
produce `compose.conflict`, with paths and source locations identifying a
|
produce `compose.conflict`, with paths and source locations identifying a
|
||||||
duplicate without exposing identity values. Missing paths and non-sequence values
|
duplicate without exposing identity values. Missing paths and non-sequence values
|
||||||
do not fail by themselves. Equivalent overlapping registrations coalesce;
|
do not fail by themselves. Equivalent overlapping registrations coalesce.
|
||||||
incompatible overlaps and invalid registrations produce `options.invalid` before
|
Incompatible overlaps and invalid registrations produce `options.invalid` before
|
||||||
source acquisition. Unused and root registrations are allowed and have no effect.
|
source acquisition. Unused and root registrations are allowed and have no effect.
|
||||||
|
|
||||||
Registration controls strict composition and supplies identity fields for parent
|
Registrations provide identity for strict composition, sequence operations,
|
||||||
lookup when surviving records in that sequence use `extends`. Dynamic selectors
|
inheritance lookup, and final validation. Dynamic selectors apply at concrete
|
||||||
apply at strict-composition and inheritance destinations without requiring the
|
strict-composition, inheritance, and final-result destinations without requiring
|
||||||
application to enumerate mapping keys. Each underlay group and the main tier has
|
the application to enumerate mapping keys. Each strict tier has independent
|
||||||
independent duplicate-identity state. Precedence assembly is unchanged: a present
|
duplicate-identity state among its peers; layered precedence and inheritance
|
||||||
higher-priority sequence replaces the lower sequence as one value, including at a
|
then apply the collection operation described below.
|
||||||
registered path.
|
|
||||||
|
|
||||||
After effective secret lookup, the shared load lifecycle validates every matching
|
Final registration checks run in both ordinary and layered loads after effective
|
||||||
sequence in the final typed projection before application semantic validation.
|
secret lookup and before application semantic validation. They examine actual
|
||||||
This catches identities introduced by typed defaults, CLI assignment, or recorded
|
final typed sequences, including values introduced by defaults, CLI, or recorded
|
||||||
resolution, in both ordinary and layered loads. Only actual sequences are checked;
|
resolution; they do not require path existence or sequence shape. Diagnostics
|
||||||
absent paths and other shapes remain the schema or application validator's concern.
|
use concrete collection and item paths and available source locations, without
|
||||||
Identity fields are read from effective typed payload regardless of authored
|
exposing identity or credential values. The guarantee ends when loading publishes
|
||||||
presence. Diagnostics use concrete collection and item paths and available source
|
successfully and does not cover later caller mutations.
|
||||||
locations, and never include identity or credential values. The guarantee ends at
|
YAML-only identity is enforced during structural composition, precedence, and
|
||||||
successful publication; later caller mutations are outside it. The accepted
|
identified inheritance; it carries no final-result guarantee after typed
|
||||||
rationale is recorded in
|
defaults, CLI, or application resolution. Applications that need that guarantee
|
||||||
[ADR 0014](adr/0014-sequence-placement-and-composition.md).
|
register the identity constraint.
|
||||||
The [maintained prompt catalog](consumers/README.md#identified-prompt-sequences)
|
The [maintained catalog examples](consumers/README.md#identified-prompt-sequences)
|
||||||
shows item path and glob imports, helper-supplied identity, and main-tier
|
show strict peers, precedence operations, inheritance, dynamic destinations, and
|
||||||
replacement of a lower-priority sequence.
|
the distinction between YAML-only declarations and application registrations.
|
||||||
When an enabled source-version mode is selected, declarations are checked in each
|
When an enabled source-version mode is selected, declarations are checked in each
|
||||||
source's own coordinates before placement and composition. Accepted non-main
|
source's own coordinates before placement and composition. Accepted non-main
|
||||||
headers are consumed before strict composition and cannot supply a registered
|
headers are consumed before strict composition and cannot supply a registered
|
||||||
@@ -872,34 +878,74 @@ record identity. Final typed decoding and application validation still run on th
|
|||||||
completed configuration.
|
completed configuration.
|
||||||
|
|
||||||
Ordinary sources, layered inputs, and selected overlays may declare collection
|
Ordinary sources, layered inputs, and selected overlays may declare collection
|
||||||
behavior under `configkit.sequences` at the document root. Each entry has a required literal
|
behavior under `configkit.sequences` at the document root. Each entry has a
|
||||||
`destination` and may specify `key` as one string or a nonempty list of strings,
|
required literal `destination` and may specify `key` as one string or a nonempty
|
||||||
plus a `mode` of `replace`, `append`, or `upsert`. These controls are removed
|
list of strings, plus a `mode` of `replace`, `append`, or `upsert`. These
|
||||||
before application decoding. A declaration destination is relative to that
|
controls are removed before application decoding. A declaration destination is
|
||||||
source's placement, so a mounted fragment's declaration is mounted with its
|
relative to that source's placement, so a mounted fragment's declaration is
|
||||||
values. Declarations from
|
mounted with its values. Declarations from strict peers must agree on identity
|
||||||
strict peers must agree on identity fields and on any explicitly supplied mode;
|
fields and on any explicitly supplied mode; omission expresses no mode
|
||||||
they apply even when the declaring source has no value at that destination.
|
preference. They apply even when the declaring source has no value at that
|
||||||
Singleton sequence contributions are validated as well as peers. A key supplies
|
destination: a key validates an existing retained sequence or remains pending
|
||||||
the identity used by `append` and `upsert`; without an explicit or retained mode,
|
until records arrive, while a mode-only declaration affects later combinations
|
||||||
a keyed collection uses `upsert`, while an unkeyed collection uses `replace`.
|
without recombining earlier tiers. A key supplies the identity used by `append`
|
||||||
`append` keeps contribution order and rejects repeated identities. `upsert`
|
and `upsert` and is checked against any application registration.
|
||||||
replaces a complete matched record at its existing position and appends new
|
|
||||||
identities in incoming order; it does not merge record fields.
|
Strict peers at an identified destination first combine distinct records in
|
||||||
|
source and list order. Duplicate identities among peers or within one
|
||||||
|
contribution fail under every mode. After strict composition, precedence and
|
||||||
|
inheritance use one operation for the assembled incoming collection:
|
||||||
|
|
||||||
|
| Mode | Behavior at source-precedence and inheritance boundaries |
|
||||||
|
| --- | --- |
|
||||||
|
| `replace` | Replace the complete lower sequence with the assembled higher sequence. |
|
||||||
|
| `append` | Retain lower records and append higher records; duplicate identities fail. |
|
||||||
|
| `upsert` | Replace matching records in full at their lower positions, retain unmatched lower records, and append new identities. |
|
||||||
|
|
||||||
|
Upsert replaces the complete matched record; it does not recursively merge
|
||||||
|
record fields. Append and upsert require identity. With no explicit mode in the
|
||||||
|
current tier, an explicit lower mode persists; if none exists, effective identity
|
||||||
|
selects upsert and its absence selects replace. Inferred modes do not persist.
|
||||||
|
Explicit modes persist at their destination until changed by a higher explicit
|
||||||
|
mode, independently of YAML identity lifetime. A declaration alone does not
|
||||||
|
clear or recombine a collection.
|
||||||
|
|
||||||
|
The presence and value kind at a precedence or inheritance boundary determine
|
||||||
|
whether a collection changes:
|
||||||
|
|
||||||
|
| Higher contribution | `replace` | `append` / `upsert` |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Absent | Leave the lower value unchanged. | Leave the lower value unchanged. |
|
||||||
|
| Explicit `[]` | Clear the sequence. | Contribute no records. |
|
||||||
|
| Explicit null or another non-sequence value | Replace the lower value, subject to application schema. | Error; the operation requires a sequence. |
|
||||||
|
|
||||||
|
An absent lower value can be initialized by an incoming sequence under any mode.
|
||||||
|
A present lower null or other non-sequence value is not absence: append and
|
||||||
|
upsert cannot combine with it. An empty sequence still requires a valid mode and
|
||||||
|
identity where applicable. Null used as an identity component inside a record is
|
||||||
|
distinct from null used as the collection value.
|
||||||
|
|
||||||
Declarations govern ordinary strict source composition, including loads with
|
Declarations govern ordinary strict source composition, including loads with
|
||||||
imports disabled, and each strict scope in layered loading. Layered groups and
|
imports disabled, and each strict scope in layered loading. Before composing a
|
||||||
main apply their resolved sequence operation between precedence tiers; a higher
|
higher tier's peers, ConfigKit makes applicable lower identity and explicit mode
|
||||||
strict scope inherits the lower identity and explicit mode before peer
|
available; after peer composition, the tier applies its resolved operation
|
||||||
composition. Overlay declarations apply after the base source graph is composed
|
against the lower collection. Selected overlays use the same collection policy
|
||||||
and must agree with retained collection identity and any application
|
after the base source graph is composed. During mapping-sibling inheritance, a
|
||||||
registration. During mapping-sibling inheritance, a parent's YAML identity can
|
parent's YAML identity can follow its collection to the child destination, while
|
||||||
follow its collection to the child destination, while the parent's explicit
|
the parent's explicit operation stays at the parent destination. The child
|
||||||
operation stays at the parent destination. A child declaration selects the
|
destination selects its operation; absent one, effective identity implies
|
||||||
operation at its destination; absent one, keyed collections use upsert and
|
upsert and its absence implies replace. Whole-sequence replacement discards
|
||||||
unkeyed collections use replace. These policies do not change CLI behavior. A root
|
lower YAML identity and uses the replacing scope's key declaration, if any;
|
||||||
`configkit.imports` declaration still requires `Options.Imports`; `NoSource` has
|
without one, the collection is unkeyed unless an application registration still
|
||||||
no declaration scope.
|
supplies identity. Replacement discards policies owned by removed records, while
|
||||||
|
an independently declared explicit mode and application registration remain
|
||||||
|
applicable. Item-local
|
||||||
|
policies follow their owning records: retaining a record retains its rules, while
|
||||||
|
whole-record upsert replacement discards the displaced record's rules. Matching
|
||||||
|
identity or reusing an index does not transfer them. These policies do not change
|
||||||
|
CLI behavior: CLI sequence assignments replace whole sequences after decoding.
|
||||||
|
A root `configkit.imports` declaration still requires `Options.Imports`;
|
||||||
|
`NoSource` has no declaration scope.
|
||||||
|
|
||||||
An empty mapping contributes no child definitions. Two empty mappings compose, and
|
An empty mapping contributes no child definitions. Two empty mappings compose, and
|
||||||
an empty mapping neither clears nor conflicts with another mapping's children.
|
an empty mapping neither clears nor conflicts with another mapping's children.
|
||||||
@@ -1076,6 +1122,12 @@ filenames unrestricted; a non-nil empty slice selects none. Defaults do not make
|
|||||||
a field applicable to selectors that do not support it, and load calls snapshot
|
a field applicable to selectors that do not support it, and load calls snapshot
|
||||||
the supplied pointers and slice before source acquisition.
|
the supplied pointers and slice before source acquisition.
|
||||||
|
|
||||||
|
A source's `configkit.sequences` declarations apply independently of import
|
||||||
|
enablement; a `configkit.imports` declaration still requires `Options.Imports`.
|
||||||
|
Sequence identities can be supplied either by these YAML declarations or by
|
||||||
|
application registrations. The [strict composition contract](#strict-document-composition)
|
||||||
|
defines their agreement, operation, and lifetime rules.
|
||||||
|
|
||||||
Acquisition visits declarations in authored order and each declaration's selected
|
Acquisition visits declarations in authored order and each declaration's selected
|
||||||
paths in namespace-path lexical order, preserving source-record and version-callback
|
paths in namespace-path lexical order, preserving source-record and version-callback
|
||||||
order. Ordinary mapping contributions in a main tier are assembled dependency-first:
|
order. Ordinary mapping contributions in a main tier are assembled dependency-first:
|
||||||
@@ -1087,9 +1139,10 @@ mapping scope, with helpers before the bodies that import them. Those local scop
|
|||||||
do not use application collection policies and are not flattened into the outer
|
do not use application collection policies and are not flattened into the outer
|
||||||
schedule. Item positions and diagnostic paths follow the resulting assembly order.
|
schedule. Item positions and diagnostic paths follow the resulting assembly order.
|
||||||
Each underlay group likewise acquires its inputs before dependency-ready assembly
|
Each underlay group likewise acquires its inputs before dependency-ready assembly
|
||||||
in one strict scope. Independent groups remain separate precedence tiers; a higher
|
in one strict scope. Independent groups remain separate precedence tiers; at a
|
||||||
tier still replaces a lower tier's sequence values wholesale. Assembly order never
|
declared or registered destination, the assembled higher sequence uses the
|
||||||
permits replacement.
|
resolved collection operation against the lower sequence. Other sequences retain
|
||||||
|
whole-value replacement between tiers. Assembly order never permits replacement.
|
||||||
|
|
||||||
Acquisition order and resolution order serve different purposes: acquisition
|
Acquisition order and resolution order serve different purposes: acquisition
|
||||||
assigns source records and callback order, while the shared scheduler determines
|
assigns source records and callback order, while the shared scheduler determines
|
||||||
@@ -1120,13 +1173,17 @@ Each declaration may include `placement: mapping` or
|
|||||||
including every match of a glob; placement is not inherited. Sequence-item
|
including every match of a glob; placement is not inherited. Sequence-item
|
||||||
placement requires a nonempty effective destination and wraps the imported
|
placement requires a nonempty effective destination and wraps the imported
|
||||||
mapping as one element of a sequence there. It does not split source sequences
|
mapping as one element of a sequence there. It does not split source sequences
|
||||||
or infer identity fields. Repeated sequences still conflict unless their path is
|
or infer identity fields. Repeated sequences combine only when the destination
|
||||||
registered through `Definition.SequenceIdentities`; registration does not
|
has an applicable YAML identity declaration or application registration; source
|
||||||
change placement or precedence behavior. Sequence records retain source
|
placement remains independent of collection identity and operation. Sequence
|
||||||
locations through placement and history; indexes describe their assembled
|
records retain source locations through placement and history; indexes describe
|
||||||
positions while source coordinates continue to identify the declaring files.
|
their assembled positions while source coordinates continue to identify the
|
||||||
Header/version policy and final application validation retain their existing
|
declaring files.
|
||||||
owners and timing; sequence registration is a strict-composition rule only.
|
Header/version policy retains its existing owner and timing. Application
|
||||||
|
registrations also enforce identity on the final effective typed configuration;
|
||||||
|
YAML-only declarations are enforced at structural combination and inheritance
|
||||||
|
boundaries. The [configuration contract](#strict-document-composition) defines
|
||||||
|
these validation boundaries.
|
||||||
|
|
||||||
An item import first opens a local mapping scope. Its body and ordinary helper
|
An item import first opens a local mapping scope. Its body and ordinary helper
|
||||||
imports compose within that record. An omitted helper destination or
|
imports compose within that record. An omitted helper destination or
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ sanitized shapes using only ConfigKit and the Go standard library:
|
|||||||
| Named presets | One-load sibling inheritance, explicit false, nested destination resolution, and source/derivation inspection | Choosing and executing a preset |
|
| Named presets | One-load sibling inheritance, explicit false, nested destination resolution, and source/derivation inspection | Choosing and executing a preset |
|
||||||
| Effective configuration diff | Same-type frozen effective comparisons for two selected files or base-versus-overlay impact | Source/options selection and consumer-owned safe presentation |
|
| Effective configuration diff | Same-type frozen effective comparisons for two selected files or base-versus-overlay impact | Source/options selection and consumer-owned safe presentation |
|
||||||
| Shared source-version checks | One `Definition.Version` policy for accepted declarations across participating source documents, with optional or required declarations and sanitized evidence | Choosing which declarations the application accepts; final assembled schema and domain validation |
|
| Shared source-version checks | One `Definition.Version` policy for accepted declarations across participating source documents, with optional or required declarations and sanitized evidence | Choosing which declarations the application accepts; final assembled schema and domain validation |
|
||||||
| Identified prompt sequences | Explicit item path/glob imports, helper-supplied IDs, reusable single-field registration, same-sequence record inheritance, and main-tier replacement of a lower-priority collection | Prompt meaning and final domain validation |
|
| Sequence catalogs | Declared collection operations, record inheritance, typed CLI and resolution, inspection, exact and wildcard application registrations | Catalog meaning and final domain validation |
|
||||||
|
|
||||||
The YAML under [`testdata`](../../examples/consumers/testdata) is loaded by the
|
The YAML under [`testdata`](../../examples/consumers/testdata) is loaded by the
|
||||||
executable examples and ordinary tests. It contains no private application data,
|
executable examples and ordinary tests. It contains no private application data,
|
||||||
@@ -184,43 +184,35 @@ import, source-location, and ownership behavior.
|
|||||||
|
|
||||||
## Identified prompt sequences
|
## Identified prompt sequences
|
||||||
|
|
||||||
[`LoadPromptCatalog`](../../examples/consumers/prompt_catalog.go) uses one
|
[`LoadPromptCatalog`](../../examples/consumers/prompt_catalog.go) shows the
|
||||||
definition registration for the literal `prompts` path and `id` field. Its
|
smaller import-focused adoption path: a registered `prompts.id` identity,
|
||||||
load-wide filename defaults accept two patterns, an explicit directory
|
directory and glob selection, a helper import that supplies an item's ID, and
|
||||||
declaration overrides those patterns, and an exclusion omits one matching
|
resource lookup through the effective source context. Its executable examples
|
||||||
candidate. A nested ordinary helper import supplies an item's ID. A separate
|
and tests are in
|
||||||
empty optional directory search is read from `SourceInfo.ImportSelections`.
|
[`prompt_catalog_test.go`](../../examples/consumers/prompt_catalog_test.go), with
|
||||||
The executable example prints both the scheduled prompt order and the single
|
complete [catalog](../../examples/consumers/testdata/prompt-catalog/config.yml)
|
||||||
empty-search outcome; the behavior test also follows a mounted resource through
|
and [required-file](../../examples/consumers/testdata/prompt-catalog/simple.yml)
|
||||||
its effective metadata origin to the declaring source context. The completed
|
fixtures.
|
||||||
main sequence replaces the lower-priority default collection as one value.
|
|
||||||
The maintained [executable example and behavior tests](../../examples/consumers/prompt_catalog_test.go)
|
|
||||||
show the scheduled result, empty-search inspection, excluded candidate, and
|
|
||||||
resource lookup without a consumer-side discovery pass. The corresponding
|
|
||||||
[complex fixture](../../examples/consumers/testdata/prompt-catalog/config.yml)
|
|
||||||
and [simple required-file fixture](../../examples/consumers/testdata/prompt-catalog/simple.yml)
|
|
||||||
are complete local examples.
|
|
||||||
|
|
||||||
[`LoadRequiredPromptCatalog`](../../examples/consumers/prompt_catalog.go) and
|
[`LoadSequenceCatalog`](../../examples/consumers/sequence_catalog.go) integrates
|
||||||
[`Example_requiredPromptCatalog`](../../examples/consumers/prompt_catalog_test.go)
|
an underlay declaration, imported main fragments, identified-record inheritance,
|
||||||
keep the smaller adoption path visible: one explicitly required file import,
|
selected overlay `append`, `upsert`, and `replace`, a typed CLI override, and
|
||||||
the same identity registration, and the same application validation.
|
recorded application resolution. Its tests and runnable example demonstrate
|
||||||
|
stable output order, whole-record upsert, provenance/history inspection,
|
||||||
|
resource lookup for inherited records, and secret-safe explanation in
|
||||||
|
[`sequence_catalog_test.go`](../../examples/consumers/sequence_catalog_test.go).
|
||||||
|
[`LoadNamespacedMapCatalog`](../../examples/consumers/sequence_catalog.go) adds
|
||||||
|
an exact root registration and a wildcard namespace registration, showing that
|
||||||
|
each concrete sequence has an independent identity scope. The same tests show
|
||||||
|
that a YAML identity declaration without an application registration does not
|
||||||
|
create final-result identity enforcement.
|
||||||
|
|
||||||
The registered `id` also identifies surviving prompt records that use
|
The examples keep prompt meaning and domain checks in the consuming application.
|
||||||
`extends: {id: "base-id"}`. ConfigKit resolves these references within the
|
The [configuration contract](../config.md#strict-document-composition) owns
|
||||||
completed prompt sequence after tier assembly, preserves the child's own ID, and
|
declaration, identity, operation, ownership, and final-validation semantics;
|
||||||
records inherited values at the child's paths. The
|
[sibling inheritance](../config.md#sibling-inheritance) defines record
|
||||||
[configuration contract](../config.md#sibling-inheritance) defines the exact
|
relationships, and the [CLI contract](../config.md#explicit-cli-overrides) owns
|
||||||
reference and nested collection behavior.
|
override ordering.
|
||||||
|
|
||||||
The example's `validatePromptCatalog` remains application-owned. It checks that
|
|
||||||
prompt names and message lists satisfy this consumer's requirements after
|
|
||||||
ConfigKit has composed, inherited, projected, and decoded the configuration.
|
|
||||||
ConfigKit does not apply identity-based overlays or enforce final uniqueness
|
|
||||||
after defaults and resolution. See the [strict composition contract](../config.md#strict-document-composition),
|
|
||||||
[import syntax](../config.md#explicit-imports), and
|
|
||||||
[ADR 0014](../adr/0014-sequence-placement-and-composition.md) for the exact
|
|
||||||
boundaries.
|
|
||||||
|
|
||||||
Known module catalogs should use canonical object entries with a module identifier
|
Known module catalogs should use canonical object entries with a module identifier
|
||||||
and typed options. A small union struct is sufficient when the available option
|
and typed options. A small union struct is sufficient when the available option
|
||||||
|
|||||||
@@ -135,12 +135,13 @@ Current behavior belongs to the configuration contract's
|
|||||||
[input destinations](config.md#input-destinations),
|
[input destinations](config.md#input-destinations),
|
||||||
[imports](config.md#explicit-imports), and
|
[imports](config.md#explicit-imports), and
|
||||||
[shared source-version checks](config.md#shared-source-version-checks) sections.
|
[shared source-version checks](config.md#shared-source-version-checks) sections.
|
||||||
Explicit sequence-item placement and registered strict composition are owned by
|
Explicit sequence-item placement, collection operations, identity registration,
|
||||||
the [strict composition](config.md#strict-document-composition) and
|
and final registered-identity validation are owned by the
|
||||||
[imports](config.md#explicit-imports) sections. The
|
[strict composition](config.md#strict-document-composition) section;
|
||||||
[maintained prompt catalog](consumers/README.md#identified-prompt-sequences)
|
[imports](config.md#explicit-imports) owns acquisition and scheduling. The
|
||||||
shows the current consumer boundary, and [ADR 0014](adr/0014-sequence-placement-and-composition.md)
|
[maintained sequence catalog](consumers/README.md#identified-prompt-sequences)
|
||||||
records the decision.
|
shows the consumer boundary, and [ADR 0017](adr/0017-collection-sequence-policy.md)
|
||||||
|
records the collection decision.
|
||||||
|
|
||||||
The completed sequence-composition roadmap, implementation plan, and resolved
|
The completed sequence-composition roadmap, implementation plan, and resolved
|
||||||
remediation record are preserved in Git history at `008d2ba` under
|
remediation record are preserved in Git history at `008d2ba` under
|
||||||
@@ -218,6 +219,7 @@ code changes. Use the component overview to find the corresponding implementatio
|
|||||||
| Import defaults, empty-selection evidence, and dependency-ready ordering | [Defaults and facade evidence](../facade_import_defaults_test.go), [engine import evidence](../internal/engine/import_evidence_test.go), [scheduler](../internal/engine/dependency_order_test.go), [scheduling integrations](../internal/engine/imports_test.go) | `go test ./internal/engine -run 'Import|ScheduleDependencies|Inheritance'`, `go test . -run 'ImportDefaults|FacadeImport'`, and `go test ./examples/consumers` |
|
| Import defaults, empty-selection evidence, and dependency-ready ordering | [Defaults and facade evidence](../facade_import_defaults_test.go), [engine import evidence](../internal/engine/import_evidence_test.go), [scheduler](../internal/engine/dependency_order_test.go), [scheduling integrations](../internal/engine/imports_test.go) | `go test ./internal/engine -run 'Import|ScheduleDependencies|Inheritance'`, `go test . -run 'ImportDefaults|FacadeImport'`, and `go test ./examples/consumers` |
|
||||||
| Native filesystem and mapping sources | [Native acquisition](../internal/engine/native_filesystem_test.go), [filesystem facade](../facade_filesystem_test.go), [mapping facade](../facade_mapping_test.go) | `go test ./internal/engine -run 'NativeFilesystem'` and `go test . -run 'TestFacade'` |
|
| Native filesystem and mapping sources | [Native acquisition](../internal/engine/native_filesystem_test.go), [filesystem facade](../facade_filesystem_test.go), [mapping facade](../facade_mapping_test.go) | `go test ./internal/engine -run 'NativeFilesystem'` and `go test . -run 'TestFacade'` |
|
||||||
| Composition, selected overlays, CLI precedence | [Composition](../internal/engine/compose_test.go), [overlay](../internal/engine/overlay_test.go), [selected overlays](../internal/engine/selected_overlay_test.go), [overrides](../internal/engine/override_test.go) | `go test ./internal/engine -run 'Compose\|Overlay\|Override'` |
|
| Composition, selected overlays, CLI precedence | [Composition](../internal/engine/compose_test.go), [overlay](../internal/engine/overlay_test.go), [selected overlays](../internal/engine/selected_overlay_test.go), [overrides](../internal/engine/override_test.go) | `go test ./internal/engine -run 'Compose\|Overlay\|Override'` |
|
||||||
|
| Sequence identity, declarations, and operations | [Identity](../internal/engine/sequence_identity_test.go), [registrations](../internal/engine/sequence_registration_test.go), [declarations](../internal/engine/sequence_declaration_test.go), [combination](../internal/engine/sequence_combine_test.go), [final facade validation](../facade_final_sequence_identity_test.go), and [consumer catalog](../examples/consumers/sequence_catalog_test.go) | `go test ./internal/engine -run 'Sequence\|Collection'`, `go test . -run 'SequenceIdentity\|SequenceRegistration'`, and `go test ./examples/consumers` |
|
||||||
| Sibling inheritance, provenance, history, sensitivity | [Expansion](../internal/engine/inheritance_test.go), [destination scopes](../internal/engine/inheritance_walk_test.go), [origins](../internal/engine/inheritance_origin_test.go), [history](../internal/engine/inheritance_history_test.go), [secrets](../internal/engine/inheritance_secret_test.go), [public loading](../facade_inheritance_test.go) | `go test ./internal/engine -run 'Inheritance\|Inherited'` and `go test . -run '^TestFacadeInheritance\|^TestFacadeInheritedSecrets'` |
|
| Sibling inheritance, provenance, history, sensitivity | [Expansion](../internal/engine/inheritance_test.go), [destination scopes](../internal/engine/inheritance_walk_test.go), [origins](../internal/engine/inheritance_origin_test.go), [history](../internal/engine/inheritance_history_test.go), [secrets](../internal/engine/inheritance_secret_test.go), [public loading](../facade_inheritance_test.go) | `go test ./internal/engine -run 'Inheritance\|Inherited'` and `go test . -run '^TestFacadeInheritance\|^TestFacadeInheritedSecrets'` |
|
||||||
| Layered loading and source equivalence | [Grouped lifecycle](../internal/engine/load_request_test.go), [layered facade](../facade_layered_test.go), [equivalence](../facade_equivalence_test.go) | `go test ./internal/engine -run '^TestGrouped'`, `go test . -run '^TestFacadeLayered'`, and `go test . -run '^TestEquivalentSourceForms'` |
|
| Layered loading and source equivalence | [Grouped lifecycle](../internal/engine/load_request_test.go), [layered facade](../facade_layered_test.go), [equivalence](../facade_equivalence_test.go) | `go test ./internal/engine -run '^TestGrouped'`, `go test . -run '^TestFacadeLayered'`, and `go test . -run '^TestEquivalentSourceForms'` |
|
||||||
| Input and relative-import destinations, mounted sources, and source ownership | [Destination engine tests](../internal/engine/destination_test.go), [tier tests](../internal/engine/destination_tiers_test.go), [import traversal and version tests](../internal/engine/destination_import_test.go), [accounting tests](../internal/engine/destination_accounting_test.go), [lifecycle inspection tests](../internal/engine/destination_import_lifecycle_test.go), [public source/error tests](../facade_destination_test.go), [resource contexts](../facade_resource_context_test.go), and [consumer examples](../examples/consumers/destinations_test.go) | `go test ./internal/engine -run 'Destination|Import|Glob|Mounted'`, `go test . -run 'Destination|Import|SourceContext|FacadeMounted'`, and `go test ./examples/consumers` |
|
| Input and relative-import destinations, mounted sources, and source ownership | [Destination engine tests](../internal/engine/destination_test.go), [tier tests](../internal/engine/destination_tiers_test.go), [import traversal and version tests](../internal/engine/destination_import_test.go), [accounting tests](../internal/engine/destination_accounting_test.go), [lifecycle inspection tests](../internal/engine/destination_import_lifecycle_test.go), [public source/error tests](../facade_destination_test.go), [resource contexts](../facade_resource_context_test.go), and [consumer examples](../examples/consumers/destinations_test.go) | `go test ./internal/engine -run 'Destination|Import|Glob|Mounted'`, `go test . -run 'Destination|Import|SourceContext|FacadeMounted'`, and `go test ./examples/consumers` |
|
||||||
|
|||||||
@@ -65,11 +65,18 @@ returns a closed cycle rotated to its smallest key; blocked dependents are not
|
|||||||
reported as cycle members.
|
reported as cycle members.
|
||||||
|
|
||||||
Import composition schedules a main tier or one underlay group as a single
|
Import composition schedules a main tier or one underlay group as a single
|
||||||
strict-scope graph. Item contributions own nested local strict-mapping scopes;
|
strict-scope graph. Applicable collection declarations are gathered for the
|
||||||
their helpers complete before the item is placed in its outer scope. Inheritance
|
scope before peer composition, including identity inherited from lower tiers.
|
||||||
uses the same ready-node rule inside each sibling mapping scope, while preserving
|
Identified peer sequences then combine distinct records in assembled source and
|
||||||
the authored mapping order in its output. These scopes do not flatten into one
|
list order; after the strict scope completes, layered assembly applies the
|
||||||
global graph, and independent precedence tiers remain separate.
|
resolved collection operation against the lower value, as defined by the
|
||||||
|
[configuration contract](../config.md#strict-document-composition). Item
|
||||||
|
contributions own nested local strict-mapping scopes; their helpers complete
|
||||||
|
before the item is placed in its outer scope. Inheritance uses the same
|
||||||
|
ready-node rule inside each sibling mapping scope, while preserving the authored
|
||||||
|
mapping order in its output.
|
||||||
|
These scopes do not flatten into one global graph, and independent precedence
|
||||||
|
tiers remain separate.
|
||||||
|
|
||||||
The main owners are [`import_selection.go`](../../internal/engine/import_selection.go),
|
The main owners are [`import_selection.go`](../../internal/engine/import_selection.go),
|
||||||
[`directory_walk.go`](../../internal/engine/directory_walk.go),
|
[`directory_walk.go`](../../internal/engine/directory_walk.go),
|
||||||
|
|||||||
@@ -9,12 +9,13 @@ Implemented component owners:
|
|||||||
|
|
||||||
- `internal/engine` owns host and native-filesystem source acquisition,
|
- `internal/engine` owns host and native-filesystem source acquisition,
|
||||||
grouped strict composition, recursive precedence assembly, per-input mapping
|
grouped strict composition, recursive precedence assembly, per-input mapping
|
||||||
and sequence-item placement, definition-registered distinct-ID sequence
|
and sequence-item placement, YAML collection declarations and operations for
|
||||||
composition within strict tiers, and immediate-parent-relative import
|
identified sequences, and application identity registrations for strict
|
||||||
placement within that assembly. Higher-priority sequences replace lower
|
composition, inheritance, and final validation. It applies the selected
|
||||||
sequences as whole values. The engine also owns dependency-ready,
|
collection operation at precedence boundaries and owns dependency-ready,
|
||||||
destination-local sibling inheritance before typed decoding, plus shared
|
destination-local inheritance before typed decoding. CLI assignment follows
|
||||||
source-version checking with sanitized declaration evidence.
|
inheritance and decoding, before application resolution. The engine also owns
|
||||||
|
shared source-version checking with sanitized declaration evidence.
|
||||||
Explicit import discovery supports declared paths, directory searches, and
|
Explicit import discovery supports declared paths, directory searches, and
|
||||||
globs; load-wide defaults and source-local empty-selection evidence cross the
|
globs; load-wide defaults and source-local empty-selection evidence cross the
|
||||||
root facade without changing acquisition order. Import and inheritance
|
root facade without changing acquisition order. Import and inheritance
|
||||||
@@ -56,9 +57,10 @@ semantics, including [input destinations](../config.md#input-destinations),
|
|||||||
[shared source-version checks](../config.md#shared-source-version-checks), and
|
[shared source-version checks](../config.md#shared-source-version-checks), and
|
||||||
[effective configuration diffs](../config.md#effective-configuration-diffs).
|
[effective configuration diffs](../config.md#effective-configuration-diffs).
|
||||||
The [strict composition contract](../config.md#strict-document-composition)
|
The [strict composition contract](../config.md#strict-document-composition)
|
||||||
owns sequence placement, registration, replacement, and history behavior; the
|
owns sequence declarations, identity, operations, ownership, and final
|
||||||
[consumer guide](../consumers/README.md#identified-prompt-sequences) shows the
|
validation; [CLI overrides](../config.md#explicit-cli-overrides) own override
|
||||||
maintained example.
|
ordering. The [consumer guide](../consumers/README.md#identified-prompt-sequences)
|
||||||
|
links maintained workflow examples.
|
||||||
The [consumer adoption guide](../consumers/README.md) owns application guidance.
|
The [consumer adoption guide](../consumers/README.md) owns application guidance.
|
||||||
The [architecture policy](../policy/architecture.md) owns contributor
|
The [architecture policy](../policy/architecture.md) owns contributor
|
||||||
boundaries; [ADR 0006](../adr/0006-public-facade.md) records the facade decision
|
boundaries; [ADR 0006](../adr/0006-public-facade.md) records the facade decision
|
||||||
@@ -74,5 +76,7 @@ records the source-version decision.
|
|||||||
sequence placement and composition. [ADR 0015](../adr/0015-shared-dependency-ready-ordering.md)
|
sequence placement and composition. [ADR 0015](../adr/0015-shared-dependency-ready-ordering.md)
|
||||||
records the shared dependency-ready ordering decision; [ADR
|
records the shared dependency-ready ordering decision; [ADR
|
||||||
0016](../adr/0016-independent-import-controls.md) records the independent
|
0016](../adr/0016-independent-import-controls.md) records the independent
|
||||||
selection controls. The [import internals](imports.md) document candidate and
|
selection controls. [ADR 0017](../adr/0017-collection-sequence-policy.md) and
|
||||||
|
[ADR 0018](../adr/0018-cli-after-structural-resolution.md) record collection
|
||||||
|
operations and CLI ordering. The [import internals](imports.md) document candidate and
|
||||||
namespace identities, discovery and scheduling, and the bounded algorithms.
|
namespace identities, discovery and scheduling, and the bounded algorithms.
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ structure as implemented when its changes land.
|
|||||||
Constraints must reflect deliberately selected requirements and decisions.
|
Constraints must reflect deliberately selected requirements and decisions.
|
||||||
Do not promote incidental implementation choices into architectural invariants.
|
Do not promote incidental implementation choices into architectural invariants.
|
||||||
|
|
||||||
The collection-policy and CLI-ordering requirements below reflect accepted
|
The implemented collection-policy and CLI-ordering constraints below reflect
|
||||||
[ADR 0017](../adr/0017-collection-sequence-policy.md) and
|
accepted [ADR 0017](../adr/0017-collection-sequence-policy.md) and
|
||||||
[ADR 0018](../adr/0018-cli-after-structural-resolution.md). The
|
[ADR 0018](../adr/0018-cli-after-structural-resolution.md). The configuration
|
||||||
[sequence roadmap](../roadmap/sequences.md) tracks the work to implement them;
|
contract owns their current behavior; these architectural constraints describe
|
||||||
the configuration contract continues to describe implemented behavior.
|
the system boundaries and guarantees that guide changes to that behavior.
|
||||||
|
|
||||||
## Success Criteria
|
## Success Criteria
|
||||||
|
|
||||||
@@ -373,8 +373,8 @@ as records survive, move, or are replaced. Identity diagnostics use paths and
|
|||||||
available origin information without exposing identity values. The guarantee
|
available origin information without exposing identity values. The guarantee
|
||||||
requires no new mutation-history system or exact reconstruction of causes for
|
requires no new mutation-history system or exact reconstruction of causes for
|
||||||
records supplied by defaults or callbacks. Exact identity equality, declaration
|
records supplied by defaults or callbacks. Exact identity equality, declaration
|
||||||
syntax, presence cases, and operation tables belong in the configuration contract
|
syntax, presence cases, and operation tables belong in the
|
||||||
when implemented; the roadmap owns those details until then.
|
[configuration contract](../config.md#strict-document-composition).
|
||||||
|
|
||||||
## Ownership And Confidentiality
|
## Ownership And Confidentiality
|
||||||
|
|
||||||
|
|||||||
@@ -6,112 +6,19 @@ commitments. Adopting a candidate requires an explicit design decision and a
|
|||||||
separate plan. Significant architectural exclusions and their rationale belong
|
separate plan. Significant architectural exclusions and their rationale belong
|
||||||
in ADRs; this document does not maintain a list of rejected proposals.
|
in ADRs; this document does not maintain a list of rejected proposals.
|
||||||
|
|
||||||
## 1. Identified record sequences
|
## 1. Recursive body merging for identified records
|
||||||
|
|
||||||
Status: deferred. PromptKit proposed this capability from its retired proposal 2,
|
Status: deferred. The implemented
|
||||||
**Namespaced Collections As Identified Records**. The original proposal is in the
|
[collection policy](../config.md#strict-document-composition) uses `upsert` to
|
||||||
PromptKit repository at
|
replace a complete matched record. Recursive merging of fields inside matching
|
||||||
`b5866dd:docs/roadmap/configuration-collections-identified-records.md`.
|
records remains a separate candidate and would revisit the whole-record update
|
||||||
PromptKit selected mounted mappings instead; this feature is not a dependency
|
boundary selected by [ADR 0017](../adr/0017-collection-sequence-policy.md).
|
||||||
of that design or a request to restore multiple installed prompt versions.
|
|
||||||
|
|
||||||
A narrower [sequence placement and composition feature](../config.md#strict-document-composition)
|
Consider this only in response to a concrete consumer need. A proposal would need
|
||||||
is implemented: consumers can place imported mappings as sequence items and
|
to define conflicts for overlapping body fields, removal of omitted fields,
|
||||||
register a single literal string identity field for duplicate-rejecting strict
|
presence and ordering, and how provenance, history, sensitivity, and resource
|
||||||
composition. Precedence still replaces sequences as whole values. This entry
|
context follow partially retained records. Any change requires a new decision and
|
||||||
tracks broader identified-record behavior that remains deferred and is not part
|
implementation plan; this entry does not alter current upsert behavior.
|
||||||
of that implemented contract.
|
|
||||||
|
|
||||||
The active [sequence roadmap](sequences.md) now selects a narrower design for
|
|
||||||
collection policy, compound scalar identities, final application-registered
|
|
||||||
identity validation, and inheritance within identified sequences. It owns those
|
|
||||||
selected behaviors and their remaining decisions. The original broader proposal
|
|
||||||
below remains background for further consideration, particularly recursive
|
|
||||||
combination of matching record bodies; it does not override the active roadmap.
|
|
||||||
|
|
||||||
### Motivation and proposed behavior
|
|
||||||
|
|
||||||
Allow applications to declare that selected sequences contain records identified
|
|
||||||
by explicit fields, while retaining sequence-shaped output for slice decoding
|
|
||||||
and effective YAML. This could make composite identities and independently
|
|
||||||
authored catalogs more convenient than encoding identity in nested mapping keys.
|
|
||||||
Current [composition](../config.md#strict-document-composition) appends distinct
|
|
||||||
records only at explicitly registered paths; other sequences remain atomic.
|
|
||||||
Selected [overlays](../config.md#selected-overlays) always treat sequences
|
|
||||||
atomically.
|
|
||||||
|
|
||||||
The proposed broader opt-in registration would extend the current reusable
|
|
||||||
application definition from one identity field to a composite identity made of
|
|
||||||
an ordered, nonempty set of distinct direct string-field names. For example,
|
|
||||||
records at `profiles` could be identified by `(namespace, id)`. Records
|
|
||||||
`(provider, brief)`
|
|
||||||
and `(application, brief)` would coexist, and a later layer could update the
|
|
||||||
provider record's temperature while retaining its backend and model.
|
|
||||||
|
|
||||||
The requested semantics, all still subject to design review, are:
|
|
||||||
|
|
||||||
- Match exact string tuples, preserving component boundaries and spelling,
|
|
||||||
including empty strings. Every contribution supplies its complete identity;
|
|
||||||
defaults, inheritance, filenames, and normalization do not supply it.
|
|
||||||
- Retain distinct identities. Matching records from strict peers recursively
|
|
||||||
compose disjoint body fields and conflict on overlapping non-mapping body
|
|
||||||
values, even equal values. Equal identity fields act as structural keys rather
|
|
||||||
than conflicts and retain their contributing source evidence.
|
|
||||||
- Higher layers recursively overlay matching bodies. A changed identity denotes
|
|
||||||
a different record, not a rename. Proposed ordering is first contribution in
|
|
||||||
precedence-assembly order; matching records keep position and new ones append.
|
|
||||||
- Reject malformed identities, non-mapping records, non-null non-sequence values
|
|
||||||
at registered paths, and duplicate tuples within one source sequence. Later
|
|
||||||
layers cannot repair malformed structural identity in an acquired contribution.
|
|
||||||
- Treat an empty registered sequence as contributing no records; whole-path null
|
|
||||||
retains ordinary conflict/replacement semantics. Unregistered sequences,
|
|
||||||
including nested message lists, retain existing atomic behavior.
|
|
||||||
- Support record inheritance within the same registered sequence using an
|
|
||||||
`extends` mapping containing the complete parent tuple. Resolve only final
|
|
||||||
active relationships after precedence, preserve the child's identity, overlay
|
|
||||||
its body on the parent's body, and consume the directive before decoding.
|
|
||||||
Preserve cancellation, missing-parent/cycle errors, and declaring resource
|
|
||||||
contexts. Existing string-based mapping-sibling inheritance stays unchanged.
|
|
||||||
|
|
||||||
Integrate ordinary and layered loads, imports, mounted paths, selected overlays,
|
|
||||||
and whole-sequence CLI overrides. Keep origins, presence, history, sensitivity,
|
|
||||||
and resource contexts attached to the correct record despite different source
|
|
||||||
and final indexes. Diagnostics must retain source locations without exposing
|
|
||||||
sensitive identity values. Final inspection may use snapshot-specific sequence
|
|
||||||
indexes; existing atomic sequence diffs need not become identity-aware.
|
|
||||||
|
|
||||||
Successful results would have valid, unique identities, including after defaults
|
|
||||||
and application resolution, without a second merge or inheritance pass. Existing
|
|
||||||
source-version checks remain independent; consumed headers cannot supply missing
|
|
||||||
record identities. No identity-selector path syntax, arbitrary merge callbacks,
|
|
||||||
wildcard registration, per-record deletion/rename operator, multiple inheritance,
|
|
||||||
or cross-path parent references are requested.
|
|
||||||
|
|
||||||
### Questions to resolve before implementation
|
|
||||||
|
|
||||||
- **Need and delivery scope:** does an active consumer benefit enough to justify
|
|
||||||
the added semantics over keyed mappings? Are composite identities required?
|
|
||||||
Staging composition before inheritance is possible but would leave part of
|
|
||||||
the request incomplete.
|
|
||||||
- **Defaults and callbacks:** do default records merge by identity or retain
|
|
||||||
existing sequence-replacement behavior? How are callback-created duplicates,
|
|
||||||
identity edits, and reordering validated and reflected in provenance?
|
|
||||||
- **Null, empty, and order:** what happens when null clears a collection and a
|
|
||||||
later layer reintroduces records? How do absent and explicitly empty sequences
|
|
||||||
interact with defaults and first-contribution order?
|
|
||||||
- **Inheritance references:** how do peers compose relationship declarations,
|
|
||||||
and how are complete references enforced without assembling partial tuples
|
|
||||||
accidentally? What happens if identity fields overlap structural controls?
|
|
||||||
- **Registration paths:** how do overlapping registrations and paths beneath
|
|
||||||
sequence indexes behave when assembly changes those indexes?
|
|
||||||
- **Evidence and lifecycle:** how are record identities mapped between source
|
|
||||||
trees, history, inheritance, callback snapshots, and final indexes without
|
|
||||||
mixing records' provenance or sensitivity? Where do identity checks run relative
|
|
||||||
to header consumption and other structural processing?
|
|
||||||
|
|
||||||
Keep the feature deferred until its consumer value and full lifecycle design
|
|
||||||
justify reconsidering the sequence-merging exclusion. A correct final sequence
|
|
||||||
alone would not establish correct inspection or disclosure behavior.
|
|
||||||
|
|
||||||
## 2. Required version declarations for selected sources
|
## 2. Required version declarations for selected sources
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Sequence Identity And Combination Implementation Plan
|
# Sequence Identity And Combination Implementation Plan
|
||||||
|
|
||||||
Status: implementation in progress; Stages 1–28 complete.
|
Status: implementation in progress; Stages 1–29 complete.
|
||||||
|
|
||||||
Audience: a Luna coding agent implementing one numbered stage per prompt, in
|
Audience: a Luna coding agent implementing one numbered stage per prompt, in
|
||||||
order. This plan starts at commit
|
order. This plan starts at commit
|
||||||
@@ -993,6 +993,15 @@ Validation: local documentation-link checks and whitespace review; run relevant
|
|||||||
example tests if executable examples changed. Reuse Stage 28's successful
|
example tests if executable examples changed. Reuse Stage 28's successful
|
||||||
code/race validation when its covered content is unchanged.
|
code/race validation when its covered content is unchanged.
|
||||||
|
|
||||||
|
**Completion:** Reconciled the configuration contract for identity equality,
|
||||||
|
selectors, declarations, operation selection and presence, ownership,
|
||||||
|
inheritance, final registered-identity validation, and post-decode CLI ordering.
|
||||||
|
Updated consumer, root, internal, development, and architecture guidance; removed
|
||||||
|
implemented behavior from the deferred feature list while retaining recursive
|
||||||
|
body merging as future work. Updated ADR implementation references and preserved
|
||||||
|
intentional historical references. Verified maintained prose/example searches,
|
||||||
|
`go test . -run '^TestLocalDocumentationLinks$' -count=1`, and `git diff --check`.
|
||||||
|
|
||||||
## Stage 30 — Audit Scaling And Verify The Completed Target
|
## Stage 30 — Audit Scaling And Verify The Completed Target
|
||||||
|
|
||||||
Scope: a bounded implementation review and final validation, not another broad
|
Scope: a bounded implementation review and final validation, not another broad
|
||||||
|
|||||||
@@ -28,9 +28,8 @@ sequences, selected overlays, and sibling inheritance. Typed defaults, CLI
|
|||||||
assignments, and application resolution retain their own combination semantics;
|
assignments, and application resolution retain their own combination semantics;
|
||||||
CLI application moves later in the loading lifecycle.
|
CLI application moves later in the loading lifecycle.
|
||||||
|
|
||||||
This scope is narrower than the deferred
|
Automatic recursive merging of matching records remains deferred
|
||||||
[identified-record sequences proposal](future.md#1-identified-record-sequences).
|
(see [future work](future.md#1-recursive-body-merging-for-identified-records));
|
||||||
Automatic recursive merging of matching records remains outside this scope;
|
|
||||||
explicit inheritance between distinct records is included. The initial
|
explicit inheritance between distinct records is included. The initial
|
||||||
declaration surface is `configkit.sequences`; `key` and `mode` shorthand on
|
declaration surface is `configkit.sequences`; `key` and `mode` shorthand on
|
||||||
imports is deferred. Application lists remain
|
imports is deferred. Application lists remain
|
||||||
|
|||||||
Reference in New Issue
Block a user