Plan sequence placement and composition
This commit is contained in:
540
docs/roadmap/implementation.md
Normal file
540
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,540 @@
|
||||
# Implementation Plan: Sequence Placement and Composition
|
||||
|
||||
Status: ready for implementation; no stages completed.
|
||||
|
||||
## Purpose and authority
|
||||
|
||||
Implement the accepted [feature roadmap](sequence-composition.md), starting from
|
||||
`2051177` (`Settle sequence placement and composition roadmap decisions`). This
|
||||
plan owns execution order and progress; the roadmap owns intent, scope, and the
|
||||
ten settled behavior decisions. The target implementer is a Luna coding agent.
|
||||
Complete the numbered stages in order. Each stage is a separate focused prompt
|
||||
and validated commit, not a request to implement the whole feature at once.
|
||||
|
||||
Read [development](../development.md), [agents](../policy/agents.md),
|
||||
[architecture](../policy/architecture.md), [testing](../policy/testing.md), and
|
||||
[documentation](../policy/documentation.md) before starting. Use the code graph
|
||||
for discovery, then inspect the current owning implementation and tests. Preserve
|
||||
unrelated work. Follow the existing commit policy after each nonempty completed
|
||||
unit; record completion and validation in this plan.
|
||||
|
||||
This planning change implements nothing. Later stages introduce private engine
|
||||
capabilities before exposing them through the root facade. Until a capability
|
||||
lands, current consumer documentation must continue to describe implemented
|
||||
behavior only. Accepted ADRs may describe the decision before implementation.
|
||||
When a stage makes behavior reachable by consumers, update its owning declaration
|
||||
comments and configuration contract in that same unit, to the implemented
|
||||
boundary. Stage 13 consolidates guidance and examples; it does not postpone those
|
||||
contract updates.
|
||||
|
||||
## Fixed design for implementation
|
||||
|
||||
### Public API and YAML spelling
|
||||
|
||||
Use these root-owned declarations and fields. Their zero values preserve current
|
||||
behavior; do not change the signatures of `Load` or `LoadLayered`.
|
||||
|
||||
```go
|
||||
type PlacementMode uint8
|
||||
|
||||
const (
|
||||
PlacementModeMapping PlacementMode = iota
|
||||
PlacementModeSequenceItem
|
||||
)
|
||||
|
||||
type SequenceComposition struct {
|
||||
Path Path
|
||||
IdentityField string
|
||||
}
|
||||
```
|
||||
|
||||
- Add `SequenceCompositions []SequenceComposition` to `Definition[T]`.
|
||||
- Add `PlacementMode PlacementMode` to `Input` and `SourceInfo`.
|
||||
- Add both `Destination Path` and `PlacementMode PlacementMode` to `Options[T]`.
|
||||
Ordinary `Load` needs the same per-source controls as the layered entry point;
|
||||
its overlay and CLI coordinates remain application-rooted.
|
||||
- YAML import declarations accept `placement: mapping` or
|
||||
`placement: sequence-item`. Omission means `mapping`, independently for every
|
||||
declaration. Retain `destination: [literal, keys]`, `path`, `glob`, and
|
||||
`optional` with their existing meanings. Do not add aliases or inferred modes.
|
||||
- Root fields and types stay root-owned. Use explicit conversions into engine
|
||||
records and a private engine mode, following the source-version-mode pattern.
|
||||
Preserve unknown numeric modes until engine preflight rejects them.
|
||||
|
||||
Validate options before acquisition. Unknown placement modes, item placement at
|
||||
an empty destination, invalid destinations/registration paths, and conflicting
|
||||
registrations use `CodeOptionsInvalid`. Registration paths use existing literal
|
||||
mapping-key destination normalization, including its current reserved-key rules;
|
||||
do not add more reserved names. Parsed numeric tokens become literal keys;
|
||||
explicit indexes and invalid paths fail. Identical registrations coalesce, unused
|
||||
registrations are permitted, and an empty/root registration is harmless and
|
||||
unused under the mapping-root model. Do not reject ancestor/descendant pairs.
|
||||
`IdentityField` is one literal string, including an empty string, not a path.
|
||||
No field-name or identity-value normalization is introduced.
|
||||
|
||||
Use `CodeImportInvalid` for malformed import placement syntax, including an item
|
||||
import whose effective destination is empty in its current mapping scope. An
|
||||
omitted item-import destination is valid when inherited placement already names
|
||||
a non-root collection. At an item root, an omitted destination names the item
|
||||
mapping itself and cannot turn that mapping into a sequence. A nested item import
|
||||
needs a nonempty effective destination within that item scope; this can come from
|
||||
its relative destination or an ordinary helper's existing placement prefix.
|
||||
|
||||
Use `CodeComposeInvalid` for malformed registered-sequence records/identities and
|
||||
`CodeComposeConflict` for duplicate identities or ordinary strict conflicts.
|
||||
Malformed-record paths identify the effective item or its identity field;
|
||||
duplicate paths identify the sequence container, with the first and conflicting
|
||||
physical locations in `Primary`/`Related`. Error messages must not interpolate
|
||||
identity strings or record bodies. Preserve deterministic reporting without
|
||||
inventing an all-errors guarantee or freezing incidental message wording.
|
||||
|
||||
### Composition, scopes, and evidence
|
||||
|
||||
1. Compile registrations once per load into an owned exact-path lookup. A strict
|
||||
tier has a separate identity table for each encountered registered sequence.
|
||||
Scan every actual sequence contribution, even one with no peer. Require map
|
||||
items and a present string identity after source-header processing and helper
|
||||
composition. Compare exact strings; accept empty strings. Non-sequences retain
|
||||
existing behavior. Distinct records append in contribution order; repeated
|
||||
identities conflict even when bodies are equal or disjoint.
|
||||
2. Keep every precedence boundary atomic for sequences. Each underlay group and
|
||||
the main tier starts new identity state. Selected overlays, CLI, defaults,
|
||||
inheritance, and application resolution do not run this identity validator.
|
||||
Registrations apply at effective literal mapping paths, never through record
|
||||
indexes. They are composition policy, not final configuration schema.
|
||||
3. Source acquisition remains depth-first and keeps current source IDs, physical
|
||||
resource identity, cycle/repetition detection, and shared budgets. Model an
|
||||
item source plus its ordinary helper imports as a local strict mapping scope.
|
||||
Ordinary imports share that scope and append relative mapping destinations;
|
||||
an explicit item import opens a child item scope. Complete each item scope
|
||||
before wrapping/validating its record in the enclosing composition. Keep its
|
||||
contribution at the declaring source's original traversal position.
|
||||
4. Carry a small private placement projection with each contribution: its scope,
|
||||
local destination, and any sequence range assigned by strict assembly. Use it
|
||||
to translate source paths into effective paths without reordering sources or
|
||||
mutating acquired trees. Authored sequence index `j` becomes `offset+j`;
|
||||
an item source's local root becomes the assigned item index. Nested projections
|
||||
compose. Do not locate records again by rescanning IDs during inspection.
|
||||
5. Keep completed trees distinct from source/history applications. Extend private
|
||||
history operations to distinguish a sequence contribution from recursive
|
||||
mapping merge: the first contribution to a collection in a tier replaces the
|
||||
previous tier/default value; later contributions append. An empty first list
|
||||
clears the prior list; an empty later list adds no items. Store only incoming
|
||||
fragments and offsets, not a cumulative list snapshot after every append.
|
||||
For item scopes, retain the initial item body and helper contributions at their
|
||||
projected item paths, so helpers retain their own history and origins.
|
||||
6. Reuse that projection in origins, history replay/query relevance, historical
|
||||
path enumeration, sensitivity, and version evidence. Public source records
|
||||
describe containers, not a new permanent record-identity address. An item
|
||||
source reports its sequence container; a mapping helper inside an item reports
|
||||
its effective mapping destination, which can include an enclosing item index.
|
||||
Output evidence may contain such indexes even though input destinations and
|
||||
registrations accept only mapping-key segments.
|
||||
|
||||
Choose private helper names and file splits to fit existing responsibilities.
|
||||
Do not introduce a provider framework, generic merge callbacks, a second loading
|
||||
lifecycle, or a public identity-selector API to implement these mechanics.
|
||||
|
||||
### Efficiency and preserved limits
|
||||
|
||||
Use one string-keyed identity map per registered sequence per strict tier, with
|
||||
ordered appends and existing indexed mapping lookup. Clone incoming records into
|
||||
owned assembly storage without repeatedly cloning the accumulated sequence.
|
||||
Registration lookup, validation, and sequence construction should be linear in
|
||||
the visited data apart from existing path/depth costs. Complete each item scope
|
||||
once; do not recursively recompose the entire ordinary-helper subtree at every
|
||||
import edge. Keep retained history fragments immutable and independently owned
|
||||
from the working tree. These are implementation choices, not a new public
|
||||
complexity, allocation, or latency guarantee.
|
||||
|
||||
Preserve current per-source, aggregate, traversal, projection, and retained-history
|
||||
limits and error families. Count acquired content once and synthetic mapping and
|
||||
sequence wrappers where introduced; include the extra sequence level in depth
|
||||
checks. Do not charge an already-accounted item/helper body again merely because
|
||||
it moves to a completed scope. Keep library-owned handles closed before returning
|
||||
on success or failure. Do not add new limits or change their existing values.
|
||||
|
||||
## Stage 1 — Record the decision and prepare private registration controls
|
||||
|
||||
Scope: one ADR and engine option normalization; no new public fields yet.
|
||||
|
||||
- Write `docs/adr/0014-sequence-placement-and-composition.md` as an Accepted ADR
|
||||
using the established format. Explain explicit item placement and registered
|
||||
duplicate-rejecting strict composition, unchanged precedence replacement, and
|
||||
their rationale in ConfigKit terms. Discuss alternatives only in Alternatives
|
||||
Considered; do not center a downstream application's semantics. Link the
|
||||
roadmap for implementation status. Do not rewrite accepted earlier decisions.
|
||||
- Add engine-owned registration records/state and normalization, reachable from
|
||||
engine `Definition`. Validate/coalesce using the fixed design above; detach
|
||||
registration slices and paths at the load boundary. Keep compiled policy
|
||||
per-load, not mutable shared Definition state or a global cache.
|
||||
- Wire preflight into both entry points without consuming a reader or opening a
|
||||
source for invalid options. Thread compiled policy through the request rather
|
||||
than rebuilding it or invoking application hooks for internal handoffs. Keep
|
||||
the existing shared source-version checker lifecycle intact.
|
||||
- Add focused normalization tests for duplicate/conflicting registrations, empty
|
||||
identity-field names, numeric/escaped literal keys, invalid index paths,
|
||||
unused/root registrations, and preserved zero-option behavior.
|
||||
|
||||
Validation: focused option tests and `./scripts/check.sh`. Completion: existing
|
||||
loads remain unchanged, with only private registered-policy input newly accepted.
|
||||
|
||||
## Stage 2 — Implement registered strict sequence validation and assembly
|
||||
|
||||
Scope: `internal/engine/compose.go` and focused composition tests.
|
||||
|
||||
- Add a policy-aware internal composer while preserving an unregistered adapter
|
||||
for existing callers/tests. Collect/check ordinary claims with current strict
|
||||
semantics; only sequence/sequence claims at registered effective paths use the
|
||||
new rule. Mapping/sequence, null/sequence, and scalar overlaps still conflict.
|
||||
- Validate every registered sequence as it is encountered, not only overlapping
|
||||
claims. Missing paths and non-sequences do not independently fail registration.
|
||||
Validate the completed contribution, not the unfinished raw item source.
|
||||
- Build identity tables once, reject duplicates within/across lists, and append
|
||||
records into owned assembly storage. Preserve mapping traversal and list order,
|
||||
explicit empty sequences, exact identity spelling, and existing error safety.
|
||||
- Return the assigned source-to-effective sequence ranges alongside the composed
|
||||
result for the following stages. Do not change overlay merging or diff logic.
|
||||
- Test distinct/mixed lists, singleton malformed records, missing/null/non-string
|
||||
fields, empty/whitespace-distinct identities, duplicate empty identities,
|
||||
identical/disjoint-body duplicates, empty lists, missing/non-sequence values,
|
||||
unused/ancestor registrations, and unchanged unregistered conflicts. Use a
|
||||
compact table of meaningful categories, not a full cross-product.
|
||||
|
||||
Validation: composition tests and `./scripts/check.sh`. Completion: the private
|
||||
composer returns the correct tree and range projection without aliasing inputs.
|
||||
|
||||
## Stage 3 — Project composition origins and claims onto appended indexes
|
||||
|
||||
Scope: composition evidence, not import acquisition.
|
||||
|
||||
- Use Stage 2's assigned ranges to project each sequence record and descendant
|
||||
onto its actual effective index. Retain physical locations and contributor
|
||||
ordering for mapping and sequence containers. Preserve field-specific origins;
|
||||
do not attribute every descendant to the sequence's first source.
|
||||
- Keep source-local claims useful for conflict reporting while effective origins
|
||||
and presence describe assembled paths. Projection must handle already-authored
|
||||
lists, mounted mapping prefixes, escaped/numeric keys, and more than one
|
||||
registered collection without using textual pointer replacement.
|
||||
- Add composition-origin tests in which a later list's local index zero becomes
|
||||
an effective nonzero index. Mutate returned/copied evidence and verify input
|
||||
and separately retained paths remain independent.
|
||||
|
||||
Validation: composition/provenance/path tests and `./scripts/check.sh`.
|
||||
Completion: correct trees and effective origins share the same record ordering.
|
||||
|
||||
## Stage 4 — Preserve append history and whole-list tier replacement
|
||||
|
||||
Scope: private history operations, replay, and precedence handoff.
|
||||
|
||||
- Extend `historyApplication` and its cloning/query/replay helpers with explicit
|
||||
sequence-contribution information from the fixed design. Keep ordinary merge
|
||||
behavior as the default. Support semantic indexed prefixes for helper events;
|
||||
current `mergeHistoryAtPath` supports mappings only and cannot be reused
|
||||
unchanged for them.
|
||||
- At every strict-tier boundary mark the first contribution at a sequence path
|
||||
as replacement and subsequent contributions as append. This boundary cannot
|
||||
be inferred from `LayerUnderlay` alone: different underlay groups share that
|
||||
layer name. Keep this information when `assemblyAccumulator.applyOverlay`
|
||||
imports a group's history applications.
|
||||
- Append replay must affect the collection and newly added record paths, not
|
||||
falsely attribute unchanged earlier records to a later source. Translate
|
||||
historical queries to the incoming fragment's local indexes for location/value
|
||||
lookup. Preserve source-level applications rather than replacing them with one
|
||||
opaque completed-tier snapshot.
|
||||
- Test before/after replay for append, explicit empty lists, independent lists,
|
||||
two underlay tiers with the same identity, main replacement, and a later whole
|
||||
list replacement/removal. Verify origin attribution and history agree with
|
||||
Stage 3's composed tree.
|
||||
|
||||
Validation: history/explanation/overlay tests and `./scripts/check.sh`.
|
||||
Completion: strict accumulation is distinguishable from precedence replacement.
|
||||
|
||||
## Stage 5 — Integrate projected paths with inspection and sensitivity
|
||||
|
||||
Scope: metadata, retained history traversal, and safe inspection.
|
||||
|
||||
- Adapt `finalizeMetadataPaths`, application-value traversal, explanation queries,
|
||||
and secret classification to Stage 4's projected operations. Do not coerce
|
||||
indexed application prefixes into mapping keys. Reuse a small common projected
|
||||
traversal/path helper where these consumers need the same translation.
|
||||
- Preserve independent effective and historical indexes, numeric key/index shape
|
||||
distinctions, removed paths, detached query results, and current sensitivity
|
||||
propagation. Classify original historical shapes before aggregating sensitivity
|
||||
by pointer; do not repeat the previously fixed shape-collision defect.
|
||||
- Ensure sensitive fields on appended records are classified at their assigned
|
||||
indexes and stay safely handled after replacement. Apply the same projection
|
||||
to source-version sensitivity evidence when that evidence is integrated in
|
||||
Stage 10. Do not classify a fragment solely at its unshifted source index.
|
||||
- Add focused tests for shifted-index metadata/history/rendering agreement and
|
||||
a replaced sensitive record. Reuse existing numeric-shape, removed-descendant,
|
||||
ownership, inheritance, and redaction cases where they already protect behavior.
|
||||
|
||||
Validation: metadata/provenance/history/explanation/secret tests,
|
||||
`go test -race ./internal/engine`, and `./scripts/check.sh`.
|
||||
Completion: the private registered composer can feed existing inspection safely.
|
||||
|
||||
## Stage 6 — Refactor acquisition into composition scopes without new behavior
|
||||
|
||||
Scope: `imports.go`, `load_input.go`, `load_request.go`, and their handoffs.
|
||||
|
||||
- Replace the assumption that traversal yields only a flat slice of already
|
||||
placed documents with ordered contribution/scope records. At this stage all
|
||||
scopes are ordinary mappings; preserve current placement and traversal exactly.
|
||||
- Separate acquisition facts from completed composition and retained history.
|
||||
Keep source-local payloads, physical locations, resource contexts, relative
|
||||
destinations, processing results, and source order available to later stages.
|
||||
Preserve input-specific filesystem contexts, tier-local repetition tracking,
|
||||
active import stacks, and load-wide shared accounting.
|
||||
- Stop reconstructing underlay contributions by treating every history
|
||||
application's `value` as a complete root document. That current shortcut loses
|
||||
projected paths and append semantics. Compose acquired contributions at the
|
||||
group boundary while preserving their source/history evidence.
|
||||
- Avoid recursive public `Load` calls, reopening files, a second parse pass,
|
||||
per-helper defaults/hooks, or resetting import limits and active/visited state.
|
||||
Preserve acquisition-first main behavior and all close/error paths.
|
||||
- Prefer existing ordinary, relative-destination, underlay, namespace, repetition,
|
||||
budget, and handle-ownership tests as the regression oracle. Add a test only for
|
||||
a real handoff risk not already covered.
|
||||
|
||||
Validation: import/destination/grouped/source-version/resource-context tests and
|
||||
`./scripts/check.sh`. Completion: this is a behavior-preserving private refactor.
|
||||
|
||||
## Stage 7 — Add the private item-placement operation and accounting
|
||||
|
||||
Scope: placement primitives and engine per-input options; not public exposure.
|
||||
|
||||
- Add the private placement mode to engine input/request/options/source records,
|
||||
with preflight validation. Keep mapping placement unchanged. A valid item mode
|
||||
needs a nonempty mapping-key destination relative to its current mapping scope.
|
||||
- Extend placement to wrap one completed source mapping in a singleton sequence
|
||||
at that destination. Preserve mapping-root input validation; do not accept raw
|
||||
source sequence/scalar roots. A nil payload stays absent, and `{}` contributes
|
||||
an actual empty item. Do not require a composition registration here.
|
||||
- Account for the sequence wrapper plus existing mapping wrappers and full
|
||||
mounted depth. Check limits before allocating oversized wrappers. Carry node
|
||||
accounting through completed scopes without charging acquired content twice.
|
||||
- Test mapping default equivalence, explicit item placement, nested literal
|
||||
destinations, absent versus empty payloads, invalid/root placement, and exact
|
||||
versus exceeded private depth/node allowances. Use test-controlled limits.
|
||||
|
||||
Validation: placement/accounting/option tests and `./scripts/check.sh`.
|
||||
Completion: the private operation places a mapping once with correct ownership.
|
||||
|
||||
## Stage 8 — Assemble item scopes and YAML path/glob imports
|
||||
|
||||
Scope: directive parsing and scoped acquisition/composition.
|
||||
|
||||
- Parse the fixed `placement` syntax and report malformed values safely. Each
|
||||
declaration's default is mapping mode; item mode is never inherited. Apply the
|
||||
same mode independently to every glob match in existing sorted traversal order.
|
||||
- An item source opens a local mapping scope. Its body and ordinary helpers
|
||||
compose strictly within that mapping, with omitted/empty helper destinations
|
||||
at the item root and other destinations relative to the immediate importer.
|
||||
A helper can supply the identity; a duplicate identity field in the item still
|
||||
fails ordinary mapping composition.
|
||||
- Complete child item scopes before wrapping them into their enclosing scope.
|
||||
Compose each scope once, preserving declaration/contribution order and source
|
||||
history. Explicit nested item imports create nested sequences; registrations
|
||||
do not descend through the enclosing record index, so repeated contributions
|
||||
to those unregistered nested sequences conflict atomically.
|
||||
- Pass completed records and their relative history/origins to the parent
|
||||
composer. Assign outer ranges there, then project the retained item body and
|
||||
helper events through those ranges. Do not emit each ordinary helper as a
|
||||
separate record or validate its identity independently.
|
||||
- Cover path and glob item imports, a helper-provided ID, relative and transitive
|
||||
helper destinations, mixed authored lists/items, optional unmatched imports,
|
||||
empty items, nested placement, default-mode independence, and physical paths
|
||||
relative to the declaring helper. Exercise native filesystem and host imports
|
||||
through existing shared-mechanism coverage rather than duplicating every case.
|
||||
- If the new syntax is now reachable through ordinary public import loading,
|
||||
document that implemented placement subset in `docs/config.md` in this unit;
|
||||
do not advertise still-private registration controls yet.
|
||||
|
||||
Validation: import/directive/glob/destination/composition tests and
|
||||
`./scripts/check.sh`. Completion: private item imports construct the agreed
|
||||
records and preserve physical acquisition evidence.
|
||||
|
||||
## Stage 9 — Wire strict policy through the complete loading lifecycle
|
||||
|
||||
Scope: ordinary/grouped engine loading and every strict-tier entry point.
|
||||
|
||||
- Pass compiled registrations and placement mode through main acquisition and
|
||||
each underlay group. Validate an authored registered list in an ordinary
|
||||
one-source load without imports, overlays, or CLI; no composition shortcut may
|
||||
bypass it. Skip only genuinely absent contributions.
|
||||
- Assemble and validate each complete strict tier before precedence can replace
|
||||
it. Reset identity maps between tiers and preserve current acquisition order.
|
||||
A malformed lower-tier list must fail even when main or overlay would replace
|
||||
it. Avoid running the checker a second time on the overlaid final tree.
|
||||
- Keep unregistered item lists atomic. Selected overlays, CLI replacements,
|
||||
defaults, callbacks, and sibling inheritance retain their current behavior.
|
||||
Do not require the final list to retain unique or even present identities.
|
||||
- Add compact engine lifecycle cases for main, an underlay group, separate tiers
|
||||
sharing IDs, `[]` clearing, unregistered conflict, a hidden lower-tier error,
|
||||
and duplicate IDs introduced by a replacement overlay/CLI/callback. Verify
|
||||
normal application validation can reject such final values when configured.
|
||||
|
||||
Validation: load/grouped/overlay/override/resolution/default tests and
|
||||
`./scripts/check.sh`. Completion: private engine policy is applied at strict
|
||||
composition boundaries only, including the one-source case.
|
||||
|
||||
## Stage 10 — Preserve source-version and structural ownership under placement
|
||||
|
||||
Scope: version path projection and existing protected-path checks.
|
||||
|
||||
- Keep source-version checking on each original source before placement, exactly
|
||||
once using the current local rule and callback lifecycle. Required/if-present
|
||||
modes retain main absence and helper-document behavior. Accepted non-main
|
||||
headers are consumed before helper/record identity validation; main's header
|
||||
stays application content. Helpers do not inherit their parent's header.
|
||||
- Default mode continues checking the configured effective path without prefix
|
||||
reinterpretation. Enabled modes derive main's protected effective path from
|
||||
its actual projection, including item indexes. Update both the request and
|
||||
version state's effective rule before later protection checks need it.
|
||||
- Audit `effectiveSourceVersionRule`, `fragmentVersionClaim`, import/underlay/
|
||||
overlay checks, override checks, inheritance checks, and resolution auditing.
|
||||
Mapping-only navigation or ancestor-sequence shortcuts cannot protect the
|
||||
wrong record or reject an unrelated strict peer merely because it appends to
|
||||
the same collection. Preserve protections of the actual main path and its
|
||||
destructive ancestor replacements; do not add an exception to version policy.
|
||||
- Retain source-local public VersionCheck paths, physical locations, full absent
|
||||
paths, and conservative failure disclosure. Use assigned projections for
|
||||
sensitivity checks of headers consumed before the final tree exists. Keep
|
||||
original semantic key/index shapes and remap nested item/helper prefixes once.
|
||||
- Keep import opt-in checks on original sources before consumed headers can hide
|
||||
a directive. Identity lookup must not count consumed headers or structural
|
||||
controls as application fields. Do not add a blacklist of identity-field names
|
||||
or use later defaults/inheritance/resolution to supply an absent identity.
|
||||
- Test main item placement in both entry points, default versus enabled version
|
||||
coordinates, consumed helper/import headers, protected-main versus unrelated
|
||||
peer paths, safe shifted evidence, optional absence below controls, and normal
|
||||
inheritance inside item mappings. Reuse existing source-version and inheritance
|
||||
regressions rather than rewriting their selected contracts.
|
||||
|
||||
Validation: source-version/version/inheritance/override/resolution tests,
|
||||
`go test -race ./internal/engine`, and `./scripts/check.sh`.
|
||||
Completion: item placement changes coordinates, not version or structural policy.
|
||||
|
||||
## Stage 11 — Expose root-owned controls and detached placement evidence
|
||||
|
||||
Scope: root facade declarations, conversions, and public integration tests.
|
||||
|
||||
- Add the exact public types/fields specified above, with declaration comments
|
||||
describing defaults, option failures, and ownership. Convert Definition
|
||||
registrations and paths, ordinary Options destinations/modes, layered Inputs,
|
||||
and successful/failed SourceInfo records in both directions as applicable.
|
||||
Update callback-entry source conversions too, not only `Result.Sources`.
|
||||
- Preserve immutable source snapshots, reader single-use behavior, callback
|
||||
lifetime, independent loads, and no public exposure of engine/parser types.
|
||||
SourceInfo reports its own selected mode; CLI/overlay sources use mapping mode
|
||||
unless an actual supported item placement was applied.
|
||||
- For a completed load, resolve nested source containers through their owning
|
||||
item projection. On an early failure retain acquired evidence without inventing
|
||||
an index that was never assigned: keep an unresolved nested source's Destination
|
||||
at its nearest resolved enclosing collection container, rather than flattening
|
||||
away an index and reporting a fictitious effective mapping path. Once assigned,
|
||||
use the projected destination. Failed-load records describe acquisition context,
|
||||
not a usable partial configuration. Do not add a public index or identity-address
|
||||
API or promise resolution of every failed source's final placement.
|
||||
- Public tests demonstrate ordinary and layered opt-in, an item-import glob,
|
||||
authored-list/item interoperability, one-source validation, helper origins and
|
||||
resource contexts at shifted indexes, both option-error entry points, detached
|
||||
source/registration paths, and unchanged zero-value callers. Keep mechanism
|
||||
edge cases in engine tests.
|
||||
- Update `docs/config.md` for the now-public registration controls, ordinary
|
||||
destination options, complete placement/evidence behavior, and strict-versus-
|
||||
replacement validation boundary. Update the architecture policy's composition
|
||||
summary to recognize the registered-sequence rule and link ADR 0014. Stage 13
|
||||
reviews and completes the surrounding guidance, not these canonical contracts.
|
||||
|
||||
Validation: focused facade tests,
|
||||
`go test . -run 'TestPublicFacadeBoundary|TestDependencyImportBoundary'`,
|
||||
`go test -race ./...`, and `./scripts/check.sh`.
|
||||
Completion: both public entry points expose the complete feature with the same
|
||||
composition rules and independently owned evidence.
|
||||
|
||||
## Stage 12 — Close cross-cutting regression and limit gaps
|
||||
|
||||
Scope: risks that require the assembled feature, not duplicate mechanism tests.
|
||||
|
||||
- Review Stage 1–11 coverage against the roadmap's ten settled decisions. Add
|
||||
only missing consequential cases. Use a representative completed load to check
|
||||
typed output, explicit zero/false/null/empty versus omission, effective origins,
|
||||
callback-entry metadata, resource contexts, history, explanation, and rendering
|
||||
agree after an append followed by a replacement.
|
||||
- Verify item/helper source canaries do not leak through duplicate diagnostics,
|
||||
errors, explanations, effective rendering, or consumed version evidence under
|
||||
existing sensitivity rules. Preserve historical redaction after index shifts
|
||||
and later removal/replacement, without imposing identity-based final masking
|
||||
rules that the existing model does not have.
|
||||
- Exercise shared aggregate accounting across item scopes/globs/underlays and
|
||||
retained-history accounting of the new operations. Confirm immutable fragments
|
||||
are counted according to existing shared-node rules and no retained cumulative
|
||||
sequence snapshots multiply history storage. Use existing close/reader seams
|
||||
for one representative nested-item failure, not a second filesystem framework.
|
||||
- Confirm effective Diff still reports atomic sequence changes and unchanged
|
||||
defaults/resolution/inheritance semantics. Review the implementation for repeated
|
||||
ID scans, growing-list clones, and helper-subtree recomposition. No timing or
|
||||
allocation threshold assertions, benchmark campaign, or new release gate is
|
||||
required; add local performance evidence only if a concrete concern needs it.
|
||||
|
||||
Validation: targeted new regressions, `go test -race ./...`, and
|
||||
`./scripts/check.sh`. Completion: no known evidence, ownership, or accounting gap
|
||||
remains hidden behind a correct final tree.
|
||||
|
||||
## Stage 13 — Document implemented contracts and provide a maintained example
|
||||
|
||||
Scope: consumer documentation and a tested in-repository adoption fixture.
|
||||
|
||||
- Update `docs/config.md` as the canonical owner for import syntax, placement,
|
||||
registered strict composition, validation timing, replacement boundaries,
|
||||
structural/version processing, source containers, and history semantics. Link
|
||||
declaration comments for API details rather than duplicating them everywhere.
|
||||
- Update `docs/policy/architecture.md`'s composition summary so its unconditional
|
||||
non-mapping-conflict description recognizes the explicitly registered sequence
|
||||
rule. Preserve consistency, ownership, and precedence principles; this feature
|
||||
does not authorize arbitrary configurable merge strategies. Link the new ADR
|
||||
and current contract. Preserve upstream provenance and locally significant
|
||||
policy decisions.
|
||||
- Update `README.md`, `docs/consumers/README.md`, `docs/internal/overview.md`, and
|
||||
`docs/development.md` only to summarize/navigate the implemented feature at
|
||||
their respective ownership boundaries. Update `future.md` to distinguish the
|
||||
implemented subset from still-potential broader identified-record features;
|
||||
do not promote their deferred semantics into this feature's contract.
|
||||
- Add a maintained fixture/test under `examples/consumers` showing independently
|
||||
authored prompt-shaped records, explicit item path/glob imports, reusable
|
||||
registration, and a lower-priority default collection replaced by the main
|
||||
list. Show that a helper can supply an ID and that final domain validation is
|
||||
consumer-owned. Use in-repository disposable data, not a live PromptKit
|
||||
dependency or a second application-side merge.
|
||||
- Keep ADR 0014 decision text immutable after acceptance; update status/navigation
|
||||
to implemented when appropriate. Do not rewrite earlier ADR decision text to
|
||||
make it appear they anticipated the extension.
|
||||
|
||||
Validation: executable example/consumer tests, local documentation-link tests,
|
||||
whitespace review, and `./scripts/check.sh`.
|
||||
Completion: current docs and tested public examples describe what actually lands.
|
||||
|
||||
## Stage 14 — Review the completed unit and hand off
|
||||
|
||||
- Read the complete implementation diff against `2051177` and the feature
|
||||
roadmap. Check all ten settled decisions and the two independent opt-ins.
|
||||
Look especially for validation accidentally extended into replacement-only
|
||||
layers, final uniqueness/schema promises, new field restrictions, wrong
|
||||
source indexes, and stale acquisition/history shortcuts.
|
||||
- Run `go test -race ./...` and `./scripts/check.sh` on the completed candidate.
|
||||
Reuse unchanged successful checks where appropriate; document actual results
|
||||
and any unresolved issue rather than claiming an unrun consumer verification.
|
||||
- Record stage completion and a concise final validation summary in this plan,
|
||||
then commit the completed nonempty unit under the normal commit policy.
|
||||
Do not create an empty completion commit or delete unfinished plans.
|
||||
- Report the new public controls, preserved precedence/ownership behavior,
|
||||
validation, and any remaining work. This sprint does not select/tag/push a
|
||||
release, alter release gates, update Go/dependencies, or update downstream
|
||||
repositories. Separately authorized release preparation can assess the public
|
||||
field additions and feature under the existing release policy.
|
||||
|
||||
Completion: the repository is clean, the feature and its evidence agree, and no
|
||||
known in-scope implementation work remains. No product decisions remain open;
|
||||
private helper names and equivalent mechanics are ordinary implementation work.
|
||||
Reference in New Issue
Block a user