Extend sequence roadmap with item placement and open decisions

This commit is contained in:
2026-10-16 14:18:36 +00:00
parent 103e10639a
commit 31fb6a9bd1
2 changed files with 308 additions and 238 deletions

View File

@@ -15,10 +15,11 @@ PromptKit repository at
PromptKit selected mounted mappings instead; this feature is not a dependency
of that design or a request to restore multiple installed prompt versions.
A narrower [identity-based sequence composition roadmap](sequence-composition.md)
now covers single-field identities, duplicate rejection during strict composition,
and whole-sequence replacement between precedence layers. The additional
capabilities below remain deferred and are not requirements of that roadmap.
A narrower [sequence placement and composition roadmap](sequence-composition.md)
now covers placing source mappings as sequence items, single-field identities,
duplicate rejection during strict composition, and whole-sequence replacement
between precedence layers. The additional capabilities below remain deferred
and are not requirements of that roadmap.
### Motivation and proposed behavior

View File

@@ -1,288 +1,357 @@
# Identity-Based Sequence Composition
# Sequence-Item Placement and Identity-Based Composition
Status: agreed feature direction; not implemented. Resolve the open decisions
below before implementation, then execute the plan in order.
Status: agreed feature direction; not implemented. This roadmap defines the
intended scope and remaining design choices. A separate staged implementation
plan will be prepared after the roadmap is finalized.
## Goal and current baseline
Allow consumers to opt selected sequences into strict composition by one explicit
string identity field. Independent fragments can contribute distinct records to
the same list; repeated identities fail composition. Keep records as sequences
for typed decoding, inspection, and effective YAML.
Let consumers assemble a list of records from independently authored mapping
files. Placement makes a source mapping one sequence item; identity-based strict
composition combines distinct items and rejects repeated identities. These are
complementary operations, with explicit consumer opt-in.
Current [strict composition](../config.md#strict-document-composition) recursively
combines mappings and rejects every other overlap. Current
Current [input destinations](../config.md#input-destinations) place source
mappings beneath mapping-key paths. Imports support immediate-parent-relative
destinations. Current [strict composition](../config.md#strict-document-composition)
combines mappings recursively and rejects other overlaps, while
[precedence assembly](../config.md#layered-loading) and
[selected overlays](../config.md#selected-overlays) replace sequences wholesale.
There is no sequence-composition registration in `Definition` today.
Neither sequence-item placement nor sequence-composition registration exists today.
This is a narrower feature than the
This roadmap covers a narrower feature than the
[identified record sequences candidate](future.md#1-identified-record-sequences).
That candidate's composite identities, recursive merging of matching records,
identity-based overlays, and record inheritance are not part of this plan.
Composite identities, recursive merging of matching records, identity-based
overlays, and record inheritance are not requested here. That scope statement
does not establish permanent architectural prohibitions.
## Agreed behavior
## Targeted behavior
### Registration and identities
### PromptKit use case
- Consumers explicitly designate each sequence path and one direct identity
field, such as `prompts` and `id`. Unregistered sequences retain current rules.
- Records in a participating sequence must be mappings containing the designated
field as a string. Missing, null, and non-string identities are invalid;
identities are not coerced from numbers or supplied by defaults or resolution.
- Compare strings exactly, without trimming, case folding, or normalization.
Whether the empty string is accepted is an open decision below.
- Retain identity fields as ordinary record content in the resulting sequence.
They are not consumed as metadata or converted into public mapping keys.
- This is a source-composition rule, not a guarantee of identity uniqueness after
application defaults and callbacks. Those retain their existing behavior;
applications can enforce final domain constraints through validation.
Each file defines one prompt directly.
### Strict composition
For a registered `prompts` sequence with identity field `id`, two separate
source fragments could contribute:
`prompt_one.yml`:
```yaml
prompts:
- id: prompt_one
text: "foo"
id: prompt.one
text: "foo"
```
`prompt_two.yml`:
```yaml
id: prompt.two
text: "bar"
```
The consumer selects item placement at `prompts` for both sources and registers
`id` as that sequence's identity field. Within one strict composition tier, the
result is:
```yaml
prompts:
- id: prompt_two
- id: prompt.one
text: "foo"
- id: prompt.two
text: "bar"
```
The composed value is:
The files need neither a filename-derived wrapper key nor their own list wrapper.
Existing sources that already contain `prompts: [...]` can contribute to the same
registered sequence under the same composition rule.
```yaml
prompts:
- id: prompt_one
text: "foo"
- id: prompt_two
text: "bar"
```
### Explicit sequence-item placement
- The destination identifies where content belongs; an explicit placement mode
selects ordinary mapping placement or placement as one sequence item. Preserve
existing behavior when the new mode is not selected. Do not infer the mode
from document shape, filename, or the presence of an `id` field.
- Support item placement for application-supplied inputs and YAML path/glob
imports. Each matched file of an item-placement glob contributes one item,
using existing match and traversal ordering. Physical import-path resolution
remains relative to the declaring file.
- Wrap the source's application mapping as one item at the destination sequence;
the new operation is not flattening a source sequence or splitting a mapping
into several items. Existing supported source forms should receive equivalent
placement behavior; this does not expand accepted source-root shapes.
- Item placement supplies structure, not identity values. Keep authored `id` and
other fields in the item. Source directives and version headers retain their
own processing rules; their interactions with the new placement context must
be resolved as described under Open Decisions.
- Preserve existing absence distinctions: `NoSource()` and an unmatched optional
import contribute nothing. An actual empty mapping contributes an empty item,
which fails the agreed identity requirement when that item participates in a
registered composition sequence.
Nested imports, placement without a composition registration, and the public
representation of item placement remain decisions rather than implicit rules.
### Identity-based strict composition
- Consumers designate sequence paths and one direct string identity field for
each. Unregistered sequences retain their current composition behavior.
- Each participating record is a mapping with the designated string field.
Missing, null, and non-string identities are invalid. Compare exact strings
without trimming, case folding, normalization, or numeric coercion. Empty
string handling remains open.
- Append distinct records in contribution order, preserving each source list's
order. Use existing deterministic input/import traversal within a tier;
identity values do not sort the result.
- Reject repeated identities both across contributions and within a single
contributing sequence, including a sequence that has no peer contribution.
Equal bodies and disjoint bodies both conflict. Never recursively combine
records with the same identity.
- An empty sequence contributes no records. Composing empty sequences succeeds;
an explicitly contributed empty sequence remains present, not absent.
- Apply these rules to main inputs and their imports, and to inputs and imports
composing each underlay group. Honor input and relative-import destinations.
Source acquisition kind must not change composition behavior.
- Invalid contributions and duplicate identities in a tier cannot be repaired
by a higher-precedence replacement. Report a normal load error and return no
usable partial result.
order. Use existing deterministic traversal within a strict tier rather than
sorting by identity.
- Repeated identities conflict across contributions and within one contributing
list, including a list with no peer contribution. Equal bodies and disjoint
bodies both conflict; matching records do not recursively merge.
- An empty sequence contributes no records. Two empty sequences compose, and an
explicitly contributed empty sequence remains present.
- Apply composition to main inputs and their imports and within each underlay
group, including placed item contributions and already-authored sequences.
Identity uniqueness is scoped to the sequence in that strict tier.
- A composition error cannot be hidden by a higher-precedence replacement. Use
normal load errors and the existing failed-load result contract.
The analogy with keyed mappings is limited: distinct keys combine, but mappings
at a shared key currently recurse. A shared record identity always conflicts
under this feature.
This differs from mapping composition at a shared key: mapping values can recurse,
whereas a repeated record identity conflicts. It does not establish final
uniqueness after defaults or application resolution. Identity values are not
supplied by those later phases; final domain validation remains application-owned.
### Precedence and other operations
Sequence replacement remains the rule between underlay tiers, between underlays
and the main tier, and for the selected overlay. An upper sequence replaces the
complete lower sequence, even at a registered path; `[]` clears it. Identities
may recur across those tiers without a cross-tier duplicate error. Null and
cross-kind precedence replacements retain current semantics.
Between underlay tiers, between underlays and the main tier, and in selected
overlays, sequences continue to replace lower sequences wholesale. `[]` clears
the lower list. The same identity can occur in different tiers without a
cross-tier duplicate error. Item placement does not turn precedence assembly
into append semantics.
Whole-sequence CLI overrides, defaults, application resolution, and built-in
sibling inheritance retain their existing semantics. This feature adds no
record inheritance, identity selector syntax, record update/delete/rename
operators, or identity-based behavior to effective-configuration diffs. Existing
atomic sequence diffs continue to compare final frozen values.
Whole-sequence CLI overrides, defaults, application resolution, and existing
sibling inheritance retain their behavior. This feature does not make records
inherit from one another by identity. Effective-configuration diffs continue to
compare final sequences atomically. Whether to validate identities in a
replacement-only overlay source is an open decision, separate from replacement.
### Inspection and diagnostics
### Existing inspection and ownership obligations
Appending records changes their effective indexes. Preserve the distinction
between an original source position and its position in the assembled sequence.
Effective presence, origins, resource contexts, history, and explanations must
refer to the correct record and its original physical source locations.
A field at source path `text` can become `prompts[1].text`; a record originally
at source index zero can acquire a different effective index after composition.
Keep original physical locations and resource contexts associated with the right
record while reflecting effective placement in presence and origin queries.
Composition history must describe the accumulated sequence correctly, rather
than replay each fragment as a whole-sequence replacement. Later actual
replacements must still retain displaced history. Equal numeric indexes in
different source lists must not make unrelated records share provenance.
History and explanations must represent accumulation within a tier and actual
replacement between tiers. Replaying each contribution as a replacement would
lose earlier records. Apply existing historical sensitivity and disclosure rules
when indexes change or sequences are replaced, and preserve detached public
records and existing input/result ownership. These are applications of current
contracts, not a new promise of persistent identity-based paths across loads.
Duplicate diagnostics must identify the conflicting source locations in
deterministic order. Avoid including identity values in diagnostic text where
sensitivity is not yet known; identify the sequence, identity field, and source
locations instead. Apply existing sensitivity and disclosure rules to successful
and failed inspection, including records whose effective indexes changed.
Retain detached public records and input/result ownership guarantees.
## Work needed
## Implementation plan
The staged plan will sequence these areas after the decisions below are settled:
### 1. Settle the remaining contract choices
- **Public API and import syntax:** introduce the selected composition
registration and placement controls at the existing root-owned boundaries;
convert them into private engine state. Define invalid-option handling and
retain current defaults for callers that do not opt in.
- **Acquisition and placement:** support item contributions in ordinary and
layered loading, input/import destinations, and glob expansion. Implement the
selected nested-import and source-version interpretation without changing
acquisition identity or physical resource resolution.
- **Composition and retained evidence:** extend claim validation, tree assembly,
origins, and history together. The current composer in
`internal/engine/compose.go` collects claims by path and stores history
applications as well as the final tree. Updating only the tree merge is
insufficient. Keep tier boundaries explicit and preserve the existing limits
and accounting through the new wrapper and accumulation operations.
- **Inspection integration:** carry source-to-effective placement through history,
explanations, sensitivity, resource contexts, and public source records. Use
the smallest internal representation that preserves those existing contracts;
this roadmap does not prescribe a new indexing or caching subsystem.
- **Behavioral verification:** cover direct and glob-imported item sources,
already-authored lists, mixed contributions, duplicate/malformed identities,
empty and absent contributions, ordering, mounted paths, and nested imports.
Verify whole-list replacement, errors hidden by later tiers, version and
structural processing, remapped indexes, resource contexts, historical
redaction, and detached records. Protect current unregistered behavior,
defaults/resolution, and atomic diffs with proportionate regression coverage.
- **Documentation and adoption:** provide a maintained PromptKit-shaped example
and update public declaration comments, configuration/inspection contracts,
consumer guidance, and relevant internal documentation when behavior lands.
Record the significant design decision under the architecture policy during
implementation; no ADR is created by this roadmap update. Keep the broader
candidate in `future.md` distinct from the implemented subset.
- Resolve the Open Decisions section and update this document with the choices.
- Select the public registration names, path interpretation, and diagnostic codes.
Duplicate claims should use the existing composition-conflict category where
appropriate; malformed registration and malformed records need distinct,
actionable diagnostics.
- Record the significant composition extension in an ADR during implementation,
under the architecture policy. No ADR is created by this roadmap-writing pass.
Completion: the public behavior and validation boundary are unambiguous, with
no accidental commitment to the broader identified-records proposal.
### 2. Add registration and pass it through the loading paths
- Add root-owned public registration types and fields using the selected API.
Convert them explicitly into private engine state; preserve the root facade
boundary and reusable definition ownership.
- Validate registrations before source processing and pass the same policy
through ordinary and layered loading, import assembly, and mounted inputs.
- Compile path lookup once per load if useful. No registrations must preserve
current behavior without introducing a new global cache or merge framework.
Completion: public callers can select sequence paths consistently across load
forms, and invalid options fail through the normal diagnostics boundary.
### 3. Extend strict composition and its retained evidence together
The current `composeDocuments` implementation in
`internal/engine/compose.go` collects claims by path, rejects non-mapping
overlaps, merges disjoint mappings, and retains origins and history applications.
Changing only the final tree merge would leave these other representations wrong.
- Extend claim validation and tree assembly for registered sequences. Validate
single contributions as well as overlaps. Track identities per sequence per
strict tier, and append cloned records in stable order. Keep duplicate lookup
proportional to record count rather than repeatedly scanning prior records.
- Keep original source locations while assigning effective indexes. Carry the
necessary placement information into claims, origins, resource contexts, and
history; do not expose a new public identity-addressing model.
- Update history/explanation replay to represent sequence accumulation. Ensure
snapshots, historical paths, sensitivity classification, and subsequent
whole-sequence replacement agree with the assembled tree.
- Integrate with ordinary input assembly and grouped assembly in
`internal/engine/load_input.go` and `internal/engine/load_request.go`.
Keep tier boundaries explicit so uniqueness is never enforced across
precedence layers accidentally.
- Preserve parser/source limits and retained-node accounting. Keep source-header
processing and structural-directive handling in their existing lifecycle
positions; do not restore consumed headers to supply record identities.
Completion: final values and their inspection evidence agree across composition
and subsequent replacement. No input mutation, source-context mix-up, or
sensitive-value disclosure is introduced.
### 4. Verify behavior at its owning boundaries
- Composition tests: distinct and repeated identities, duplicates in one list,
malformed records and identity types, empty strings according to the chosen
decision, empty lists, ordering, missing paths, and null/cross-kind cases.
- Loading tests: imports, underlay groups, mounted and relative destinations,
equivalent source forms, and conflicts hidden by later layers. Demonstrate
that separate tiers may reuse identities and still replace whole lists.
- Metadata and inspection tests: records appended from the same source index
acquire distinct final indexes while keeping correct locations, history,
resource contexts, and sensitivity. Cover later replacement and historical
redaction, including a failure before final classification.
- Public integration tests: registration conversion and reuse, normal load-error
behavior, unchanged unregistered sequences, selected-overlay and CLI
replacement, defaults/resolution behavior, and atomic effective diffs.
- Add a small maintained consumer example showing two fragments composing and
a selected overlay replacing the result. Include only enough cases at each
layer to catch distinct failure modes.
Run focused tests during development, then the everyday validation prescribed
by the [development guide](../development.md#baseline-validation). Run ownership
or concurrency checks where required by the change. No independent performance
benchmark campaign is part of this plan; keep measurement separate from the
busy-host environment discussed in the performance audit.
Completion: new behavior is covered without weakening the existing atomic
replacement and default-behavior regressions.
### 5. Publish the implemented contract in repository documentation
- Document the public API beside its declarations. Update the configuration
contract's composition, inspection/history, and precedence sections, and the
consumer guide and maintained example together when implementation lands.
- Update the architecture policy and component overview only where the
implemented boundary changes. Keep the broader candidate in `future.md`
clearly distinct from this delivered subset.
- Retire this completed roadmap through the usual documentation lifecycle.
Release preparation and publication remain separate work.
Completion: current documentation describes the delivered feature, and no
future proposal is presented as implemented behavior.
Completion means the PromptKit example works through public inputs and imports,
composition and replacement behave as agreed, and configuration values agree
with their inspection evidence. Validation follows the
[development guide](../development.md#baseline-validation). This documentation
pass neither implements the feature nor runs performance benchmarks.
## Open Decisions
### 1. Public registration ownership
Recommendations below are proposals, not accepted restrictions. Resolve them
before preparing the staged implementation plan. Exact public names and error
code spellings can be selected with the API design; implementation details that
do not affect observable behavior need not become additional contracts.
**Recommendation:** place a collection of path/identity-field registrations on
`Definition`, shared by ordinary and layered loading. This describes how the
application's configuration is composed and avoids diverging registrations
between load forms. Choose final type and field names before coding.
### 1. Public controls and ownership
**Alternative:** place registrations on load options. That allows one definition
to be composed differently per invocation, but duplicates configuration across
ordinary/layered options and makes composition semantics less visibly part of
the application's reusable definition.
**Recommendation:** put sequence path/identity-field registrations on `Definition`
and an explicit placement mode beside input destination controls, with equivalent
YAML import syntax. Expose the corresponding choice for ordinary loading too.
This separates reusable composition policy from placement of particular sources
and keeps default placement unchanged.
### 2. Path matching, overlapping registrations, and unused rules
**Alternative:** put composition registrations on load options, allowing different
composition rules for each invocation of one definition. That offers flexibility
but duplicates policy across ordinary/layered load forms. A dedicated item-input
constructor is also viable instead of a mode field, but needs equivalent import
syntax and a clear way to combine destination and source options.
**Recommendation:** interpret paths in effective configuration coordinates after
input/import placement, using literal mapping-key segments initially. Reject
duplicate registrations for the same path; allow a registration to match no
source value. These rules fit mounted collections without requiring discovery
of which optional sources will be present. Restricting paths to mapping segments
would be an explicit initial scope choice, not an existing library constraint.
### 2. Destination and registration paths
**Alternative:** support exact sequence-index segments too, including registered
sequences nested inside appended records. This is more expressive, but requires
choosing whether a rule matches source indexes or composed indexes, and how
matching behaves as earlier lists contribute records. Settle that interpretation
and overlapping registration behavior before supporting these paths. Wildcard
or identity-selector matching is not needed for the agreed use case.
**Recommendation:** use literal mapping-key paths to identify destination
sequences and match composition registrations after placement. This fits the
existing destination vocabulary and the requested `prompts` use case. Preserve
existing destination validation; do not silently add new reserved names. Keep
empty/root item destinations invalid if they would replace the currently required
mapping document root with a sequence. These are proposed scope choices, not
already-approved new validation rules.
### 3. Empty identity strings
Allow unused registrations for optional configuration. Coalesce identical
registrations and reject conflicting identity rules for the same path. For
ancestor/descendant registrations, apply a rule only where its literal path
actually reaches a sequence; it does not implicitly traverse every record.
**Recommendation:** accept the empty string as an exact identity; two empty
identities conflict. Presence and string type are sufficient for the composition
algorithm, and applications can require nonempty domain identifiers themselves.
**Alternative:** support explicit sequence-index paths, including sequences inside
appended records, or sequence-valued configuration roots. These are expressive
extensions, but require decisions about source versus effective indexes and
root decoding. Nested-item destinations arising through imports also need the
context rule in decision 4; they must not accidentally introduce wildcard path
matching. Rejecting even identical duplicate registrations is another viable
option, but catches redundant setup at the cost of an additional restriction.
**Alternative:** require nonempty identities. This catches likely authoring
mistakes earlier, but adds a domain restriction beyond uniqueness and string
type. Whitespace trimming or normalization would still remain out of scope.
### 3. Item placement without identity registration
### 4. Null and non-sequence values at registered paths
**Recommendation:** allow item placement independently. It contributes a singleton
sequence; without a registration, two present sequences still conflict during
strict composition, while precedence still replaces them. This keeps placement
orthogonal and allows a consumer to place a single item without inventing an
identity rule.
**Recommendation:** treat registration as selecting how actual sequences
compose, not as a general schema assertion. Preserve existing rules for absent,
null, scalar, and mapping values: non-sequence overlaps retain ordinary strict
composition behavior, and final decoding/validation checks application types.
Two sequence values use the new rule; sequence/null and sequence/mapping overlaps
remain conflicts. No later layer can hide an actual strict-composition conflict.
**Alternative:** require every item destination to have a composition registration.
This catches a likely setup omission early, but unnecessarily couples placement
to identity validation for consumers that only need one item. Implicitly appending
unregistered sequences would change the agreed opt-in composition boundary.
**Alternative:** require every present non-null source value at the path to be a
sequence, even when a later tier would replace it. This catches misplaced
configuration earlier but makes registration an additional source-shape rule.
If selected, define null handling explicitly rather than treating it as empty.
### 4. Imports declared inside an item-placed source
### 5. Validation of replacement-only source sequences
**Recommendation:** compose ordinary imports into that source's item mapping;
interpret their relative destinations inside the item. An explicit item-placement
import then contributes an item to a sequence within that context. A collection
manifest can import multiple peer prompt files as items at `prompts`. Do not
implicitly inherit item mode and turn every helper import into another prompt.
This permits helper fragments without requiring each helper to declare an ID.
**Recommendation:** require well-formed, internally unique identities for actual
source sequences at registered paths, including selected-overlay sequences.
This makes source authoring consistent while preserving whole-sequence
replacement and permitting identities to recur across tiers. Do not extend the
rule to synthetic CLI replacements, defaults, or callback-generated values;
final domain validation remains application-owned.
This recommendation introduces an item-local composition context. Specify how
omitted and empty destinations resolve, how nested contexts are represented,
and how registrations address any nested destination sequences consistently
with decision 2 before accepting it.
**Alternative:** validate only source sequences participating in a strict tier,
leaving selected-overlay sequences subject solely to existing decoding and
application validation. This keeps the check strictly tied to the composition
operation, but allows the same list to succeed as an overlay and fail as a base
contribution. Choose this boundary explicitly; replacement semantics alone do
not settle whether an overlay's own duplicate identities are invalid.
**Alternative:** keep inherited destinations anchored at the enclosing collection
and require an explicit mode on each imported contribution. That can simplify
peer-item expansion, but ordinary helper mappings would collide with the
collection sequence rather than extend the declaring record. Inheriting item
mode as well would make peer imports concise, but needs an explicit way to
request helpers within one record. Do not reject nested imports merely to avoid
settling their interpretation.
### 5. Identity-validation boundary and structural processing
**Recommendation:** validate each contributed record after its source directives
and applicable version-header processing, and after any item-local mapping
composition chosen in decision 4, but before collection composition and later
precedence replacement. Ordinary helper imports can therefore supply fields of
one record; each completed record still needs its identity. Defaults and
application callbacks do not supply missing identities at this stage.
Keep existing `extends` semantics: an item itself has no mapping-sibling namespace
for record inheritance, while mappings inside an item may have one. Consumed
structural fields or headers do not become application identity values. Determine
whether a proposed identity-field selection overlaps such controls through the
existing processing rules rather than inventing a blanket field-name blacklist.
**Alternative:** require the directly authored item file to contain its own ID
before processing helpers. This simplifies early duplicate detection but adds a
restriction not needed for the requested assembled-record behavior. Validating
only the final configuration is not sufficient to catch the agreed strict-tier
conflicts that later replacements would hide.
### 6. Empty identities and literal field names
**Recommendation:** accept empty string identity values, with repeated empty
values conflicting. Interpret the designated direct field name literally,
including unusual or empty YAML mapping keys where existing processing permits
them. Presence and string type suffice for comparison; applications can impose
stronger naming rules through their own validation.
**Alternative:** require nonempty identity values or nonempty field names. This
can catch mistakes earlier but imposes additional domain conventions. Exact
comparison without trimming or normalization remains the agreed behavior.
### 7. Non-sequence values at registered paths
**Recommendation:** let registration select how actual sequences compose, without
asserting that every source must contain a sequence at that path. Missing values
and non-sequence values retain existing composition and decoding behavior.
Sequence/null and sequence/mapping overlaps still conflict; item placement
contributes an actual sequence and follows those same rules.
**Alternative:** reject every present non-null non-sequence source value at a
registered path, even if a higher tier would replace it. This catches misplaced
configuration earlier but makes registration an extra source-shape validator.
If selected, define null behavior explicitly rather than equating null with an
empty sequence.
### 8. Validation of replacement-only sequences
**Recommendation:** apply identity validation where source sequences participate
in strict composition, including singleton contributions, and preserve existing
validation for replacement-only selected overlays and synthetic CLI overrides.
Defaults and callbacks retain the agreed behavior. This keeps the new check tied
to its purpose and avoids broadening source validation merely for uniformity.
This revises the previous draft's recommendation to validate overlay identities.
**Alternative:** also require replacement-only source sequences to have valid,
unique identities. Authoring rules would be more uniform, but this would reject
some overlay configurations that do not need identity matching to replace a
list. It needs explicit acceptance; whole-sequence replacement does not imply it.
### 9. Source-version checks for item-placed main inputs
**Recommendation:** keep enabled source-header checks source-local before item
placement and preserve accepted header consumption/retention rules. Define the
main header's effective path, protected-path behavior, and reported evidence
using its actual item placement. Check ordinary and layered loading and all
source-version modes, including default-mode effective-path interpretation.
A sequence identity rule must not silently become a version policy.
**Alternative:** initially support item placement only for non-main contributions,
leaving the main document in its existing mapping placement model. This covers
a collection manifest importing prompt items but adds a source-role restriction
beyond the requested general input capability. Prefer resolving the main-path
semantics over imposing that restriction for implementation convenience.
### 10. Public placement evidence and diagnostics
**Recommendation:** retain `SourceInfo.Destination` as the effective
container destination and add the minimum placement information needed to
identify item mode. Use existing effective-path metadata for final indexes;
a source need not have one permanent item index after replacement. Diagnostics
should identify conflicting locations and paths without exposing identity
values before sensitivity is known. Reuse existing error categories where they
accurately describe the failure.
**Alternative:** report a resolved item path directly in source records, with
explicit semantics for replaced items, helper sources, and different historical
indexes. This is convenient for consumers but introduces a broader inspection
contract. A permanent identity-addressed source path is not needed for this use
case. Decide the public evidence shape without promising stable indexes across
loads or changes in contribution order.