diff --git a/docs/adr/0011-input-destinations.md b/docs/adr/0011-input-destinations.md index b6e0477..6476da4 100644 --- a/docs/adr/0011-input-destinations.md +++ b/docs/adr/0011-input-destinations.md @@ -3,8 +3,8 @@ ## Status Accepted. The [input-destinations roadmap](../roadmap/input-destinations.md) -owns implementation status and the [implementation plan](../roadmap/implementation.md) -owns sequencing and completion evidence. +owns implementation status. The completed implementation plan and evidence are +preserved at `315f464:docs/roadmap/implementation.md` in Git history. ## Date diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 3e0cc39..9fe8bc2 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,580 +1,394 @@ -# Implement configuration input destinations +# Implement relative import destinations -Status: complete. Stages 1–12 are implemented and audited. The -[feature roadmap](input-destinations.md) owns the approved behavior and rationale; the -[consumer request](promptkit-feature-request.md#public-acceptance-scenarios) -supplies the public acceptance scenarios. This document owns execution and -completion evidence. Planning baseline: `6353598`. +Status: planned. Execute Stage 1 through Stage 9 in order, one focused stage per +Luna implementation prompt. The +[feature roadmap](relative-import-destinations.md) owns the approved target and +syntax; this document owns implementation decisions, sequencing, and evidence. + +Planning baseline: `b2db323`, including input-destination remediation at +`315f464`. The previous completed input-destination implementation record is +preserved at `315f464:docs/roadmap/implementation.md` in Git history. The broader +[consumer request](promptkit-feature-request.md#requested-addition-relative-import-destinations) +also proposes independent specification headers, which are outside this plan. ## Working instructions -- Start each stage with `AGENTS.md`, [development.md](../development.md), the - applicable policies, and working-tree inspection. Use graph-first code - discovery. Preserve unrelated changes and previously completed stages. -- Implement only that stage and its supporting tests/documentation. Mark it - complete here with actual commands and evidence, then commit the nonempty - validated unit with a short plain-English message. Subsequent stages remain - planned. A stage is not complete solely because its narrow tests pass. -- Keep early mechanics private until the complete engine behavior is ready. - Root destination fields land in Stage 10. Ordinary root loading must remain - working throughout. Do not publish a partially supported public placement API. -- Follow the existing engine/document/YAML boundaries. Reuse strict composition, - recursive overlay, sibling inheritance, paths, history, and sensitivity. - No dependencies, toolchain changes, alternate mergers, mount registry, - per-fragment lifecycle, import-destination syntax, resource discovery, or new - release gates are needed. These are scope boundaries, not new prohibitions - on separately approved future work. -- Update current-behavior documentation when public behavior lands; keep future - claims here or in the roadmap until then. Add the ADR in Stage 1 under the - documentation policy's accepted-decision exception. -- Use focused offline tests while iterating; run `./scripts/check.sh` before - committing production changes. Documentation-only stages need whitespace and - local-link checks. Stage 12 adds full ownership/race validation. Tests protect - observable behavior, not wrapper allocation or helper-call counts. Reuse - coverage rather than repeat an entire loading matrix at every layer. -- No benchmark campaign or public complexity guarantee is required. Prefer - straightforward bounded walks and wrapping each acquired contribution once; - avoid rescanning all preceding contributions for every new input. -- Do not push, tag, publish, update downstream dependencies, or retire unfinished - records. Release compatibility review is separate from publication. +- Start with `AGENTS.md`, [development.md](../development.md), applicable policies, + and working-tree inspection. Use graph-first code discovery and preserve + unrelated changes. Read existing import and placement contracts before edits. +- Implement one stage at a time with its relevant tests/documentation. Record + actual commands, revisions, results, and limitations here; mark only completed + stages and commit each validated nonempty unit with a plain-English message. +- Follow the root-owned facade and private engine/document/YAML boundaries. + Reuse paths, placement, composition, inheritance, version ownership, history, + and resource contexts. No public Go entry point, source-header API, namespace + registry, or second merger is needed. +- Specification-header checking and consumption remain deferred. Ordinary + `version` data, the main-owned checker, exact-path numeric conversion, and + callback timing keep their existing behavior. Examples must work without the + broader request's combined header example. +- Roadmap exclusions define this delivery, not new permanent prohibitions. Do + not add directory discovery, caps, key-name grammars, root-reset syntax, + arbitrary callbacks, or stronger security/release guarantees. +- Keep Stage 2 behavior-preserving before Stage 3 accepts new syntax. Once + accepted, syntax must work through existing import entry points, not only path + imports or only root loads. +- Use focused offline tests while iterating and `./scripts/check.sh` before + committing production changes. Documentation-only work needs whitespace and + local-link checks. Ownership race checks belong to Stages 6 and 9. Reuse + unchanged coverage; do not assert helper-call counts, allocation identity, + exact diagnostic prose, or a cross-product of already protected cases. +- No independent benchmarks, performance thresholds, dependency changes, + toolchain upgrades, or new release gates are required. Prefer copying path + segments once per declaration and existing bounded tree processing; introduce + no public complexity guarantee. +- Do not push, tag, publish, upgrade downstream dependencies, rewrite accepted + ADR decisions, or remove unfinished work. Completed records retire during + separately authorized release preparation. ## Resolved implementation decisions -1. Add root-owned `Input.Destination Path` and `SourceInfo.Destination Path`, - mirrored privately in engine input/source records. Extend `loadInput` and - explicit root/engine conversion and cloning. No new loading entry point, - public wrapper type, option, or origin field is needed. Ordinary `Load` - continues to supply root placement. -2. The zero path means root. Validate `Path.valid()` and reject every explicit - index segment, including a negative index. Normalize parsed tokens to literal - mapping-key segments: `/0` means the key `0`, not sequence element zero. - Empty, dot, dot-dot, slash-containing, tilde-containing, and numeric keys keep - existing semantic-path meaning. Do not split dots, interpret filesystem - traversal, enforce identifier grammar, or add namespace uniqueness. -3. Reject destination segments equal to `configkit` or `extends`: placement - would introduce a reserved mapping key with a mapping value. Substrings such - as `myextends` are ordinary keys. This preserves the approved structural - rules rather than adding an application naming policy. Source-root import - directives are still processed before placement. -4. Validate destination shape/reservations for all declared inputs during - grouped option preflight, before reading any source. Reuse - `CodeOptionsInvalid` for invalid destination declarations; include the - offending semantic path when representable, with no fabricated physical - location. An invalid source still follows existing source-option validation. - A valid destination on `NoSource` contributes no nodes, source record, or - budget charges. No extra error type or exact message contract is introduced. -5. Separate acquired source syntax from application placement. Retain original - parsed source metadata for filesystem/directive handling. Strip source-root - directives, then wrap each application body at the normalized destination - before fragment version checks and strict composition. Imports inherit the - same destination transitively. Do not wrap both a source application and its - recomposed result; every retained application must already use effective - coordinates. Content roots remain mappings under existing source contracts. -6. Wrapping a body at `Keys("a", "b")` creates `{a: {b: body}}` as private - document mappings. Actual body nodes and entries keep their physical source - coordinates. Introduced mappings/entries use the contributing document's root - location as a documented source fallback, not purported authored coordinates. - They have the same contributing source ID and create no synthetic source. - Retained history trees remain immutable and separate from assembly mutation. -7. A present empty body creates explicit destination mappings, including an - import-only source whose application body is empty. It still cannot clear - lower mappings. A missing optional import and `NoSource` remain absent. Empty - source text remains the existing invalid document, not an empty mapping. -8. `VersionRule.Path` stays an effective application path. Check main once after - its own imports compose and before underlays/overlay/CLI, at the existing - phase. Imported and underlay claims are checked against placed application - content, including scalar/null/sequence ancestors replacing a protected path. - A mapping ancestor with no protected descendant is not a version claim. - Mounted domain `version` fields are ordinary data. Existing inheritance, - selected-overlay, CLI protection and exact-path numeric conversion remain; - no nested blanket conversion or additional fragment checker is introduced. -9. Placement does not alter physical source identity, filesystem namespace, - source IDs, acquisition order, imported-from locations, or resource contexts. - Repeated physical sources in one strict group still fail even at different - destinations. The same physical source in separate tiers retains the existing - independent source applications/records and each record's own destination. - Overlay and CLI source records have root `Destination`; they are not mounted - merely because main is mounted. Active layered overlays retain their explicit - independent filesystem selection and application-root meaning. -10. Value-level paths use effective coordinates. Keep genuine source-local - import-directive diagnostics and parse/read failures at their original - locations; do not invent a logical child path when parsing cannot identify - one. Prefix existing application-relative diagnostic paths exactly once - where available. Preserve structured codes, related physical locations, - deterministic ordering, and value-free messages. -11. Use current depth/node limits, not a new destination cap. With root depth - zero, each destination segment adds one level and, under `countInputNodes`, - one mapping node plus one key. Retain current raw input accounting (including - directives); charge only the additional `2 * segmentCount` synthetic nodes - per acquired body, once, to the shared input budget. Placement adds no bytes, - acquired sources, import nesting, or glob visits. Validate placed application - depth and per-document node bounds before composition; share accounting - across inputs and imports. Precheck wrapper depth/count before allocating - wrappers. Use existing source/import limit diagnostics in their acquisition - contexts; retain projection, expansion, and history bounds independently. - Root placement adds no charge or new rejection. NoSource adds none either. -12. Cloned source records include independently owned destination paths at every - existing publication boundary: results, load errors, metadata/inspection, - callback input information, and root conversion. Passive resource contexts - remain keyed by the real source identity; inspection must work without an - open configuration handle after load. This does not extend caller-owned - filesystem or callback resource lifetimes. +### Syntax and validation -## Stage 1 — Record the decision and capture the baseline +1. Add one optional import-declaration field, `destination`, beside existing + `path`/`glob` and `optional`. Its value is a sequence of strings. Omission + and `[]` mean zero additional segments. Null, a scalar (including a pointer + string), and any non-string member produce `CodeImportInvalid`. No coercion: + quote numeric-looking keys when YAML would otherwise parse them as numbers. +2. Construct a relative `Path` of literal mapping keys and reuse + `normalizeDestination`. Empty strings, dots, dot-dot, slash/tilde-containing, + and numeric-looking strings keep their literal meaning. Existing exact + `configkit` and `extends` reservations apply. Do not trim keys, split + dots/slashes, clean filesystem paths, infer sequence indices, impose a + collection grammar, or add syntax aliases. +3. Validate shapes/reservations in `parseImportDeclaration`, before traversal + can suppress an optional missing target or unmatched glob. Invalid shapes + identify source-local `/configkit/imports//destination`; invalid + members identify its indexed child and actual member location. Follow + `nodeImportDiagnostic` conventions and keep messages value-free. Preserve + unknown-field, duplicate-key, path/glob, and optional rules. No new public + error code/type, all-errors aggregation, or error-order guarantee is needed. -Status: complete. Scope: decision record and evidence, no feature code. +### Traversal and source records -1. Read the roadmap, request, relevant policies, and ADRs 0001, 0003, 0006, - 0008, and 0009. Inspect the owners identified in the roadmap and the function - map below. Confirm the baseline and worktree before starting. -2. Run `./scripts/check.sh`; record the commit, Go version, and results here. - Locate existing coverage for root loading, strict underlays, version ownership, - repeated sources, history, resource contexts, and detached records. -3. Write `docs/adr/0011-input-destinations.md` after confirming the number is - unused. Record the approved input-placement decision as Accepted, with the - roadmap owning implementation status. Follow the repository ADR format. - Focus on ConfigKit, put rejected options only in Alternatives Considered, - and avoid negative parallelism elsewhere. No PromptKit-specific semantics. -4. Record the compatibility assessment under the release policy: adding fields - preserves zero-value/keyed-literal use, but callers using unkeyed literals - for `Input` or `SourceInfo` must migrate to keyed literals. Treat the feature - as minor-release work; select a version and write its note only during - separately authorized release preparation. +4. Add a private relative-destination field to `importDeclaration`. Pass the + immediate parent's effective destination explicitly through + `walkDeclarations`. Append each declaration's relative path once and pass + that already computed child destination to `visitPath`. Recursive walks use + the child's effective destination. Remove the single + `importTraversal.destination` context rather than mutating/restoring it. +5. Add a small private destination-append helper in `destination.go`, unless a + semantically suitable general helper already exists. Copy semantic segments + into owned storage without pointer-string round trips, filesystem operations, + or repeatedly extending a growing prefix with `Path.Key`. Its inputs are + validated mapping paths. Place each body once, not once per ancestor. +6. Every glob match receives the same computed child destination. + `expandImportGlob` remains about physical matching. Turning a match into a + path declaration must not append its suffix again. Nested context must not + leak into siblings, later matches, or later inputs. +7. Use the child destination for source records, placement, fragment-version + checks, wrapper accounting, and recursion. Keep source-record creation at its + existing point so imports that later fail retain their effective destination. + `ImportedFrom` still identifies the physical path/glob declaration, not the + destination list. Source IDs, namespaces, acquisition order, active cycles, + physical identity, and strict-group repetition rules remain unchanged. +8. Remove the post-traversal assignment in `assembleBaseInputTracked` that + overwrites every imported source's destination. Set the selected entry's + per-load `parsedSource.source.Destination` before import-context setup so + early `sourceInfos` fallback copies retain entry placement. Leave correctly + assigned children untouched. Preserve `315f464`'s Mapping value-error + rebasing and root behavior; do not rebase syntax/read/directive failures. -Validated: `./scripts/check.sh` (go1.26.8 linux/amd64) passed on candidate -`d3d468a8b47d780787fca329ff65b107d98ca59f`; this includes formatting, -whitespace, local documentation links, tests, vet, and build. The planning -baseline `6353598bd6cce2eb78a5fe990e144cc0cadf1280` is present in history. The -worktree was clean before this stage. +### Assembly, limits, and compatibility -Coverage located for later destination work: +9. Strip source-root directives before placing each application body and + checking imported version ownership. Existing composition/history retain the + placed source applications. Strict peers conflict, tiers recursively overlay, + sequences stay atomic, and sibling inheritance follows precedence. Do not add + post-load merging or per-fragment decoding, defaults, callbacks, or headers. +10. Reuse current depth, node, source, byte, import-depth, glob-entry, projection, + and history limits. Charge each actual body's wrappers once using its full + accumulated destination, not only the suffix. Preserve raw source accounting. + Placement adds no source bytes, source records, import nesting, or glob + visits beyond existing accounting. A glob declaration/ancestor walk itself + adds no payload. Omitted/empty suffixes reproduce baseline charges. +11. Malformed syntax fails even when optional input is absent. Resource charging + remains tied to actual contributions: a valid optional no-match creates no + source or wrappers; an actual empty body materializes its full destination. + Use existing placed-body bounds and source/import diagnostics. Add no + destination-length limit or rejection solely because an absent optional + contribution's unused path would be deep. +12. Preserve authored locations and source-root fallback for synthetic mappings. + Resource contexts remain physical and survive inheritance/overlays. + Metadata, history, sensitivity, rendering, diffs, detached records, and + complete-on-return behavior reuse their existing mechanisms; no new + inspection API or retained loading handle is needed. +13. This is additive YAML functionality. Existing valid imports and Go + signatures keep their contracts. Treat it as minor-release work; version + selection, notes, retirement, and publication remain separate tasks. Do not + edit published release notes. -- Root and equivalent source loading: `TestEquivalentSourceFormsPreserveInputSemantics` - (`facade_equivalence_test.go`) and - `TestFacadeLayeredZeroUnderlaysMatchesOrdinaryLoad` (`facade_layered_test.go`). -- Strict underlays and group budgets: `TestGroupedLoadStrictConflictsRepetitionAndBudgets` - and `TestGroupedLoadPrecedenceSourceOrderAndSingleLifecycle` - (`internal/engine/load_request_test.go`). -- Version ownership and imported claims: `TestLoadRejectsImportConflictsAndFragmentVersions` - (`internal/engine/imports_test.go`) and version-path coverage in - `internal/engine/load_test.go`. -- Repeated physical sources: `TestRepeatedImportsAcrossTiersAndReaderConsumption` - (`facade_equivalence_test.go`). -- History and source contexts: `TestUnderlayHistoryRetainsLaterMappingContributors` - (`facade_underlay_origins_test.go`) and - `TestFacadeSourceContextsFollowOriginsWithoutQueryIO` - (`facade_resource_context_test.go`). -- Detached records: `TestLoadMetadataReflectsDefaultsInputAndDetachedRecords` - (`internal/engine/load_test.go`) and - `TestMetadataQueriesReturnDetachedRecords` (`internal/engine/metadata_test.go`). +## Stage 1 — Capture the baseline and record the extension -The decision is recorded in [ADR 0011](../adr/0011-input-destinations.md). -Compatibility assessment: adding the two public fields breaks callers using -unkeyed literals for `Input` or `SourceInfo`; keyed and zero-value use remains -compatible. The release policy permits the intentional pre-1.0 contract change -in a minor release when the release note states impact and migration. Version -selection and release-note preparation remain out of scope until separately -authorized. No feature code or current behavior contract changed. +Status: planned. Scope: baseline evidence and one ADR; no production code. -## Stage 2 — Add private destination normalization and wrapping +1. Read the feature roadmap, relative-import request/acceptance rows, applicable + policies, ADR 0011, and the owner map below. Confirm the worktree and baseline. + Run `./scripts/check.sh`; record revision, local Go version, results, and + environmental limitations here. +2. Locate existing parser, host/native import, glob, repetition, version, + placement-accounting, resource, history, and facade coverage. Root and + inherited placement are the compatibility baseline; header rows in the + broader request are not acceptance requirements for this plan. +3. Write `docs/adr/0012-relative-import-destinations.md` after confirming the + next unused number. Record the selected syntax and immediate-parent-relative + semantics as an Accepted extension to ADR 0011. Use the repository format. + Keep implementation status in the roadmap and rejected choices only under + Alternatives Considered. Focus on ConfigKit, without downstream semantics. +4. Note the extension in ADR 0011's status/navigation if needed; preserve its + accepted decision text. Record the additive minor-release assessment without + selecting a version or adding release gates. -Status: complete. Scope: pure private mechanics with bounded unit tests. +Validate: whitespace and local-documentation-link checks. Done: baseline and +decision are recorded; implemented behavior is unchanged. -1. Add a small engine helper file for normalized mapping-only destinations and - constructing placed document bodies. Follow decisions 2–7; keep helpers - private and avoid introducing a second path abstraction. -2. Validate invalid paths, explicit indices, and exact reserved tokens. Normalize - parsed numeric tokens into keys, preserving literal text and pointer escaping. -3. Build wrappers without mutating the supplied tree. Preserve body locations; - give introduced entries/mappings the source-root fallback. Implement depth and - node measurement/prechecks usable with existing limits, including the extra - synthetic-node count; aggregate charging is wired in Stage 7. -4. Cover root identity/equivalence, nested empty mapping, literal/escaped/numeric - keys, invalid index/path, exact versus substring reserved keys, owned paths, - unchanged body coordinates, and bounded wrapper checks. Do not count helper - invocations or fix an allocation strategy in tests. +## Stage 2 — Refactor traversal to explicit per-document placement -Validated with `go test ./internal/engine -run 'Destination|PlaceDocument'` -and `./scripts/check.sh` (go1.26.8 linux/amd64); both passed. The private -helpers normalize mapping-only destinations, preserve authored nodes and source -coordinates, and check per-document depth/node bounds before allocating wrappers. -No loader accepts a new public field yet. +Status: planned. Scope: private context plumbing; old syntax remains unchanged. -## Stage 3 — Integrate private non-import input placement +1. Add the relative-destination slot to `importDeclaration`, initially zero for + all parsed declarations. Add the destination-append helper and bounded + literal-path/ownership tests using existing Path conventions. +2. Give `walkDeclarations` the parent's destination, compute each child once, + pass it into `visitPath`, and pass that child path to recursive walks. Remove + the traversal's uniform destination field and update private callers/tests. + Initialize the first walk from the entry Input destination. +3. Use the per-call destination in records, `placeDocument`, version checks, + and wrapper accounting. Leave glob matching unchanged; each match receives + the computed child path without re-appending relative segments. +4. Narrow source-record assignment per decision 8. Check import-context/open + failures, imported parse failures, successful imports, and the completed + Mapping error regression. Exported fields/signatures remain unchanged. +5. Add one small engine fixture with private nonzero declaration destinations + proving accumulation and sibling/glob isolation before parsing is enabled. + Public syntax and complete acceptance follow Stage 3. -Status: complete. Scope: engine request plumbing and ordinary acquired bodies. +Validate: `go test ./internal/engine -run 'Import|Glob|Destination|Grouped'`, +`go test . -run 'Destination|FacadeLayered'`, and `./scripts/check.sh`. +Done: baseline loads remain equivalent; all placement consumers use explicit +document context and no uniform setter can erase per-import placement. -1. Add destination fields to engine `Input`, `loadInput`, and `SourceInfo`. - Preserve ownership through engine `LoadLayered` request construction, - `cloneSourceInfo`, and source-record copies. Keep the root facade unchanged. -2. Extend grouped preflight to validate/normalize destinations before source - reads. Use the existing diagnostic accumulator and options-invalid category. - Ordinary `Load` supplies root placement through its existing request adapter. -3. Thread placement into `assembleBaseInputTracked` without confusing raw - `parsedSource` with effective `assembledInput.document`. Preserve the root - path through existing wrappers/callers. For imports-disabled acquisition, - validate disabled directives on raw content, place the body, and retain the - destination on the acquired source record. NoSource still short-circuits. -4. Use engine loads to cover mounted main and underlay bodies, omitted versus - explicit root destinations, empty mapping versus NoSource, and preflight - rejection without consuming a test-owned reader. Reuse current source-kind - acquisition tests; full source equivalence is verified publicly in Stage 10. +## Stage 3 — Accept and document the selected YAML syntax -Validated with `go test ./internal/engine -run 'Destination|PlaceDocument|Grouped'` -and `./scripts/check.sh` (go1.26.8 linux/amd64); both passed. Private non-import -placement reaches assembly, with root behavior unchanged. Imports are the next -private integration step. +Status: planned. Scope: directive parsing and first complete public behavior. -## Stage 4 — Carry placement through import acquisition +1. Parse sequence-of-strings `destination` in `parseImportDeclaration`. + Construct literal keys, normalize with existing destination validation, and + retain the relative path. Use `CodeImportInvalid` and actual declaration or + member nodes for failures; retain path/glob locations independently. +2. Add table-driven parser coverage: omission, `[]`, valid nonempty lists, + empty/slash/tilde/dot/numeric strings, null/scalar/non-string failures, and + exact reserved versus substring keys. Preserve mutual exclusion of path/glob, + unknown-field failures, and optional's boolean type. One invalid optional + missing path and one unmatched glob prove validation precedes suppression; + no full cross-product is needed. +3. Add public ordinary-root `Load` and mounted layered entry cases. Include + path/glob imports, a child with its own import, a subsequent sibling, and + multiple matches. Assert final values and individual source destinations; + context leakage must fail the test. +4. Update canonical import/input-destination sections in `docs/config.md` when + syntax lands. Qualify uniform inherited-placement claims with omission; + explicit suffixes accumulate from the immediate parent. No Go API change. -Status: complete. Scope: source-local directives and placed imported applications. +Validate: focused engine import/glob/destination tests, public import-destination +tests, local links, and everyday check. Done: syntax works across existing +import-capable entry points and acquisition forms, not a silently ignored or +root/path-only subset. -1. Thread a normalized destination through `loadImportedDocumentsTracked`, - `loadImportedWithAccessTracked`, and `importTraversal`, retaining root defaults - for current private callers. Place the selected body's application content - after `splitImportDirectives`; do the same for every imported body. -2. Set placement on selected/imported source records, including error records - once a source has been acquired. Keep `ImportedFrom` at the physical directive. - Run imported `fragmentVersionClaim` against placed bodies and retain placed - bodies in `state.documents` before `composeDocuments` builds applications. -3. Leave filesystem joins, containment, glob traversal, optional missing inputs, - active cycles, visited identities, and acquisition IDs/order unchanged. - Destination must not become part of the repeated-source identity key. -4. Test native and host transitive imports, nested source-root directives, - import-only bodies, and mounted imported protected versus ordinary version - paths. Verify a repeated file at two destinations in one group still fails, - including an import/direct-input alias. Reuse cycle/containment regressions. +## Stage 4 — Verify composition and effective version ownership -Validated with `go test ./internal/engine -run 'Destination|PlaceDocument|Import|Grouped'` -and `./scripts/check.sh` (go1.26.8 linux/amd64); both passed. Retained imported -contributions have effective placement and physical source identity, with no -double wrapping or application-level directive leakage. +Status: planned. Scope: assembly interactions; reuse existing algorithms. -## Stage 5 — Complete strict tiers and main version ownership +1. Cover disjoint same-destination contributions, different destinations, + ancestor overlaps, and collisions with explicitly wrapped content. Equal and + unequal non-mapping overlaps remain strict conflicts. Verify an upper tier + cannot repair a lower strict-group conflict. +2. Exercise deliberate upper-tier overrides: recursive maps, retained omitted + fields, atomic sequences, and an ordinary version-only override retaining + the rest of the prompt. Overlay/CLI paths stay application-rooted. +3. Verify accumulated placement governs imported protected-path/ancestor claims + and ordinary nested `version` fields remain payload. Main's hook runs once + at its existing point; exact-path numeric conversion does not spread. Reuse + current inheritance/overlay/CLI version guards where they prove unchanged + behavior. +4. Test repeated physical sources at distinct logical destinations, including + direct-input/import aliases and cycles reached through changed placement. + Keep original inclusion routes/locations; add no namespace uniqueness. -Status: complete. Scope: assembly and version interactions, not a new merger. +Validate: `go test ./internal/engine -run 'Import|Destination|Compose|Overlay|Override|Version|Grouped'` +and everyday check. Done: relative placement changes neither tier semantics nor +the main-owned version contract. -1. Review `acquireUnderlayGroup`: version checks must use placed content, and - documents taken from `acquired.composition.applications` must already be - placed. Recompose strict peers with ordinary `composeDocuments`; preserve - per-source applications, origins, UnderlayIndex, and input accounting. -2. In `executeLoadRequest`, main's version check uses its placed main/import - composition at the existing point. `assembleLayeredInput` recursively overlays - completed underlay groups beneath main, selected overlay, and CLI as before. - Do not mount the final assembly or prepend main's destination to upper tiers. -3. Test disjoint same-destination peers, different destinations, equal and unequal - conflicts, ancestor/descendant destinations, and a strict conflict despite an - upper override. Verify recursive mapping overlays, atomic sequences, null, - explicit false/zero, and version-only domain overrides retaining lower fields. -4. Exercise mounted main with a nested VersionRule, absent root declarations, - imported/underlay direct and ancestor claims, and nonclaiming mapping ancestors. - Check the hook runs once and does not inspect each fragment independently. - Preserve exact configured-path integer conversion and ordinary nested typing. +## Stage 5 — Verify accumulated resource accounting -Validate: destination/composition/overlay/version/grouped tests and everyday -check. Validated with `go test ./internal/engine -run 'LayeredDestination'`, -`go test ./internal/engine -run 'Destination|Composition|Overlay|Version|Grouped'`, -and `./scripts/check.sh` (go1.26.8 linux/amd64); all passed. The new mounted -cases verify strict same-tier conflicts and disjoint composition, independent -destinations and nested paths, recursive/atomic overlay behavior, explicit -null/false/zero, and main-only nested version checking after imports compose. -Done: placed and authored equivalents agree on values and conflicts; main -ownership and lifecycle timing are preserved. +Status: planned. Scope: limit regressions and any necessary narrow correction. -## Stage 6 — Reconcile diagnostic coordinate systems +1. Audit `placeDocument`, `destinationWrapperNodeCount`, `importAccounting`, + and composition totals. Each body uses the full effective destination for + depth/wrapper nodes, charged once. Keep raw directives in acquired accounting. + Synthetic wrappers add no bytes, source count, glob visits, or import depth. +2. Add below/at/above cases with small private limit fixtures where existing + seams permit. Cover a short suffix whose accumulated path exceeds placed + depth, empty bodies at nested destinations, and several glob matches sharing + aggregate nodes. Derive counts from fixture helpers, not copied defaults. +3. Verify valid optional missing/unmatched sources create no source record or + wrappers, including when their unused destination would be deep. An actual + empty mapping is explicit. Reuse Stage 3 for malformed optional declarations. +4. Confirm later overlays/CLI and history/expansion checks see correct totals. + Reuse baseline tests; introduce no cap, performance assertion, or new failure + precedence merely for this feature. -Status: complete. Scope: useful paths without fictional source locations. +Validate: focused import/destination/limit/override tests and everyday check. +Done: accumulation cannot bypass current bounds or falsely charge absent input. -1. Audit early acquisition, import, fragment-version, and composition failures. - Use one narrow path-prefix translation where diagnostics genuinely identify - application content; do not blanket-prefix every diagnostic or double-prefix - diagnostics already produced by placed trees. -2. Preserve syntax/read/directive locations and related import sites. Value - conflicts and later typed/resolver/validation failures use effective paths - but original content coordinates. Invalid introduced structure identifies - the destination declaration rather than a nonexistent source wrapper line. -3. Add focused assertions for a mounted conflict with two real sources, a mounted - decode or validation error, an imported version error, invalid destination, - and malformed source-local directives. Test stable codes/paths/locations and - nil results, not whole messages or callback choreography. +## Stage 6 — Preserve diagnostics, source inspection, and resource contexts -Validate: destination/diagnostic/import/version/decode tests and everyday check. -Validated with `go test ./internal/engine -run 'LayeredDestinationDiagnostics'`, -`go test ./internal/engine -run 'Destination|Diagnostic|Import|Version|Decode'`, -and `./scripts/check.sh` (go1.26.8 linux/amd64); all passed. The mounted -conflict, decode, and imported-version assertions use effective application -paths with authored source locations; invalid destinations have no physical -location; malformed source-root directives retain their authored path and -location. Later value diagnostics are produced from placed trees, while directive -diagnostics retain their raw source coordinates. Post-review remediation also -rebases known Mapping value-builder failure paths, which are produced before -placement. `TestFacadeDestinationMappingFailurePaths` covers mounted main and -underlay failures, escaped keys and sequence-index intent, cycles, unchanged -root paths, and unchanged source-constructor failures. Its mounted value cases -failed before the fix and pass afterward. -Done: diagnostics consistently distinguish application paths from source syntax. +Status: planned. Scope: coordinates, detached records, and resource ownership. -## Stage 7 — Complete shared placement accounting +1. Check entry/child/grandchild source records' individual destinations, kinds, + IDs, physical paths, and ImportedFrom locations. Include public failure + records after imported parse and effective-path version/composition errors; + preserve existing reporting completeness. +2. Directive failures identify source-local paths and actual locations. + Composition/typed-validation failures use effective paths with authored + content coordinates. Keep syntax/read failures and Mapping rebasing at their + established boundaries; never prefix all diagnostic paths. +3. Use temporary host files and a native-filesystem fixture to prove physical + joins stay relative to the declaring file as destinations change. Exercise + byte/reader/mapping entries with existing explicit filesystem contexts where + applicable; imported files keep existing acquisition contracts. Reuse source + equivalence tests rather than duplicate a whole matrix. +4. Through resolution/result APIs, follow a direct and inherited resource field + to its original filesystem/base, including a lower value surviving override. + Application/test code owns opening the resource. +5. Mutate returned copies, repeat queries, and compare independent loads to + verify detached destination storage. Confirm library acquisition handles + close before return and existing failure cleanup remains covered. -Status: complete. Scope: resource bounds with no new public limit system. +Validate: focused public import/destination and engine resource/provenance/ +diagnostic/import tests, `go test -race ./internal/engine`, and everyday check. +Done: logical placement is inspectable without changing physical identity, +filesystem lifetime, or the public facade boundary. -1. Wire Stage 2's prechecks and synthetic-node charges into both tracked ordinary - acquisition and import traversal, using `importAccounting` and current limit - structures. Charge each source body once, including empty import bodies. -2. Preserve existing raw byte/source/node accounting and imported directive - inspection. Additional wrappers count in per-body depth/node checks and - shared aggregate nodes; recomposition must not charge them again. Ensure - selected overlays and CLI start from totals including placement charges. -3. Test below/at/above relevant bounds using small private limit fixtures where - existing seams permit; add a narrow private seam if necessary. Cover deep - body plus destination, many shallow mounted inputs, imported wrappers, and - empty mappings. Verify root placement and NoSource do not add charges. - Preserve history/expansion limits; do not turn fixture values into defaults. +## Stage 7 — Verify inheritance, history, sensitivity, and diffs -Validated with `go test ./internal/engine -run 'Destination|Import|Grouped|Overlay|Override'` -and `./scripts/check.sh` (go1.26.8 linux/amd64); both passed. New coverage in -`TestDestinationPlacementCountsAgainstSharedNodeBudget`, -`TestMultipleMountedInputsSharePlacementCharges`, -`TestImportedEmptyBodiesChargeEachDestinationWrapper`, -`TestSelectedOverlayAndCLIUsePlacementNodeCharges`, and -`TestNoSourceAndRootPlacementAddNoWrapperCharges` checks totals below, at, and -above the boundary, multiple shallow inputs, imported empty bodies, and charging -of upper tiers from mounted inputs. `TestPlaceDocumentRootAndBounds` continues -to cover per-document depth/node boundaries; existing grouped accounting tests -cover unchanged raw source/byte charging. Done: placement cannot bypass current -budgets and introduces no unrelated caps. +Status: planned. Scope: retained placed data and one final application lifecycle. -## Stage 8 — Preserve provenance, history, and source resource contexts +1. Resolve a sibling parent/child supplied by separate relative imports after + all tiers. Reuse nested inheritance/cancellation tests; add no cross-collection + lookup semantics. +2. Compare a relative-import load with equivalent wrapped/per-input-placed + inputs. Values, presence, and safe diff equality agree; physical source + locations may naturally differ. +3. Cover historical contributions, replaced/removed descendants, effective-path + and field-tag sensitivity, inherited fields, and a recorded derived value + using existing dependencies. Check effective rendering, explanations/history, + and bilateral diffs with disposable canaries. Preserve the existing + Redacted/HiddenChanged distinction. +4. Verify defaults, decode, resolution, secret lookup, and semantic validation + use the final assembled shape without per-fragment callbacks. No source header + is checked, consumed, coerced, or retained as a new evidence type. Failures + still return no usable partial result. -Status: complete. Scope: engine inspection and retained evidence. +Validate: engine `Import|Destination|Inheritance|Secret|Sensitivity|Explain|Diff` +tests, representative facade tests, and everyday check. Done: the feature feeds +existing inspection/completion mechanisms without reconstructing them. -1. Audit `compositionOrigins`, `completeCompositionOrigins`, application replay, - metadata construction/finalization, and source-record cloning against placed - applications. Prefer feeding placed trees into existing processing rather - than adding another path-offset index or rewriting final metadata afterward. -2. Verify explicit destination containers, actual leaves, composite origins, - superseded/removed descendants, and root/source fallbacks. Historical and - effective indexes keep independently owned paths and existing shape semantics. -3. Preserve source-ID resource contexts through imports, surviving lower-tier - values, and inheritance. Test completed-result and resolution-time context - queries against real relative files, without making ConfigKit open the - referenced application resource or retain loading handles. -4. Exercise the same physical source in separate tiers with different placement, - inspect each source record, and verify independent destination paths. Repeat - inspection after comparison and independent loads to detect retained mutation. +## Stage 8 — Demonstrate ordinary and mounted collection entries -Validated with `go test ./internal/engine -run 'Destination|Metadata|Provenance|History|Resource|SourceContext'`, -`go test -race ./internal/engine`, and `./scripts/check.sh` (go1.26.8 -linux/amd64); all passed. `TestLayeredDestinationsRetainOriginsHistoryAndDetachedRecords` -checks synthetic-container fallback locations, authored leaf coordinates, -composite origins, removed-descendant history, and the same host file retained -at distinct destinations in separate tiers before and after comparison and an -independent load. `TestLayeredImportedInheritedValuesRetainResourceContexts` -uses real temporary files to verify resolution-time and completed-result -relative-resource lookup through an imported surviving parent and its inherited -child. Existing metadata and resource-context tests continue to cover detached -records and loading-handle closure. Done: inspection explains effective -placement and physical origin without consumer reconstruction. +Status: planned. Scope: maintained public examples and their behavior tests. -## Stage 9 — Verify final inheritance, sensitivity, and lifecycle integration +1. Add a compact ordinary-root example: its entry imports metadata and a fragment + with `destination: [prompts]`, using existing `Load` import opt-in and no + Input destination or header policy. +2. Add/adapt a maintained layered example under `examples/consumers`. Mount an + entry beneath collection keys and let its YAML declare metadata/prompt/profile + placement, including a nested import. Keep the application schema declaration + main-owned. The entry has no consumed specification header; collection/prompt + version labels are ordinary payload. +3. Include peer composition, local sibling inheritance, an upper-tier version-only + domain override, and a source-relative resource query where representative. + Reuse current example types/fixtures; keep imports compact and necessary. +4. Test final values, source placement, presence, and resource context through + supported APIs. Applications select sources/tiers and interpret resources; + add no source rewriting, generic merging, or provenance reconstruction. + Link maintained examples from the consumer guide. -Status: complete. Scope: complete private engine behavior before facade exposure. +Validate: `go test ./examples/consumers`, applicable executable `Example` tests, +local links, and everyday check. Done: ordinary and layered workflows operate +without the deferred source-header proposal. -1. Resolve sibling inheritance only after full source precedence using the - existing expansion path. Cover a child and parent supplied by separate peers, - nested destination-local siblings, cancellation, and an inherited relative - resource retaining its declaring context. Cross-collection search is unchanged. -2. Reuse existing inheritance-version, overlay, and CLI guards; add targeted - mounted cases for actual protected paths and their ancestors. Do not reject - unrelated inheritance merely because it shares a mapping ancestor. -3. Test effective-path secret predicates, field tags and recorded dependencies, - superseded classified values, safe effective output/history/explanation, and - bilateral diff redaction using disposable canaries. Compare mounted versus - explicitly wrapped loads for equal effective values and no differences. -4. Verify defaults, decoding, resolution, secret lookup, and validation execute - once on the final shape; failures return no usable result. Reuse existing - ordinary-load lifetime/ownership coverage and add mounted protection where - placement creates a distinct risk. +## Stage 9 — Reconcile documentation and audit the complete feature -Validate: destination/inheritance/secret/sensitivity/explain/diff/lifecycle tests -and everyday check. Validated with -`go test ./internal/engine -run 'Destination|Inheritance|Secret|Sensitivity|Explain|Diff|Load|Version|Grouped' -count=1`, -`go test -race ./internal/engine`, and `./scripts/check.sh` (go1.26.8 -linux/amd64); all passed. +Status: planned. Scope: final consistency and evidence; no publication work. -`TestLayeredDestinationInheritanceUsesFinalSiblingScopes` verifies parent and -child contributions from separate peers, a higher-tier parent update, nested -destination-local siblings, and cancellation. `TestLayeredDestinationInheritanceDoesNotSearchOtherCollections` -keeps sibling lookup local. `TestLayeredMountedVersionProtectionCoversInheritanceAndUpperTiers` -protects inherited values, scalar/null ancestors, consumed directives, selected -overlays, and CLI overrides at mounted paths while allowing nonclaiming mapping -ancestors and unrelated inheritance. The coverage exposed an ancestor gap in -the existing inheritance-version check; it now applies the shared fragment claim -logic to the transferred parent subtree. - -`TestLayeredDestinationLifecycleAndSensitiveInspectionUseFinalShape` checks one -defaults/resolution/secret-lookup/validation lifecycle, final mounted decoding, -field tags and effective-path predicates, superseded history, and safe effective -output/explanation against canaries; it compares mounted and explicitly wrapped -loads for equal configuration and no diff. `TestLayeredDestinationDiffUsesBilateralSensitivity` -checks redaction from either side and recorded dependencies, and -`TestLayeredDestinationDecodeFailureReturnsNoResultOrLaterCallbacks` checks a -mounted decode failure returns no result. Stage 8's -`TestLayeredImportedInheritedValuesRetainResourceContexts` continues to verify -the declaring context for inherited relative resources. Done: approved engine -semantics integrate without per-fragment loading or a post-return processing -pass. - -## Stage 10 — Expose the root-owned facade and public acceptance tests - -Status: complete. Scope: the two public fields and complete consumer behavior. - -1. Add `Input.Destination Path` and `SourceInfo.Destination Path` to root types. - Extend `toEngineInput`, `fromEngineSourceInfo`, `toEngineSourceInfo`, and all - source publication paths with owned conversion. Run existing public/import - boundary tests; expose no engine nodes, aliases, or bridge methods. -2. Document zero/root behavior, mapping-only paths, main/underlay parity, - inherited import placement, source-coordinate fallback, and source ownership - beside declarations. Update the configuration contract for implemented input - destinations, preserving canonical ownership of shared semantics. -3. Add external-package public-load coverage for equivalent host file, native - fs.FS file, byte, reader, and Mapping sources. Cover default/root destinations, - literal escaped/numeric keys, empty mapping, NoSource, and invalid declarations. - Include one public mounted main case, not just underlays. -4. Add representative public tests tying final configuration to metadata, - source placement, history, resources, callbacks, and safe diffs. Mutate returned - record copies and repeat queries/loads to confirm detachment. Reuse engine - matrices; public tests demonstrate supported integration rather than every - private branch. Confirm failed loads expose detached source destinations. - -Validated with `go test . -run 'Destination|FacadeLayered|PublicFacadeBoundary|DependencyImportBoundary' -count=1`, -`go test -race ./...`, and `./scripts/check.sh` (go1.26.8 linux/amd64); all -passed. - -`TestFacadeInputDestinationsAcrossSourceKinds` exercises host, native -filesystem, bytes, reader, and mapping inputs with literal escaped and -numeric-looking mapping keys. `TestFacadeDestinationRootEmptyMappingNoSourceAndInvalidPaths` -covers omitted/empty root placement, empty mapping presence, absent `NoSource`, -invalid index/reserved destinations, and reader preflight. `TestFacadeImportedSourcesRetainInputDestination` -checks public transitive import placement. `TestFacadeMountedMainAndUnderlayInspectionResourcesAndDiff` -ties mounted main/underlay values to metadata, both source destinations, callback -source context, relative-resource access during and after loading, history, safe -effective/explanation rendering, and bilateral diff redaction; it also mutates -returned records and confirms later queries and comparisons remain unchanged. -`TestFacadeFailedLoadExposesDetachedSourceDestination` verifies failure records, -and `TestSourceInfoDestinationConversionsAndCopies` covers root/engine source -record conversion. Existing public-boundary tests pass with the new root-owned -fields. Done: destination selection and inspection are available through the -supported ConfigKit import path. - -## Stage 11 — Add maintained simple and collection-style consumer examples - -Status: complete. Scope: executable adoption examples with consumer-owned types. - -1. Add a minimal mounted-fragment example using `Input.Destination` in an - ordinary layered load. Show literal keys and root-default compatibility - without introducing consumer parsing or generic merge helpers. -2. Add one representative collection assembly under `examples/consumers`: peer - prompt/profile fragments, collection metadata with ordinary `version`, a - source-root import, local sibling inheritance, and an intentional higher-tier - version-only override retaining the body. Keep the application VersionRule - main-owned. Use a controlled native filesystem or temporary files. -3. Demonstrate effective-path inspection plus source-relative resource lookup - during resolution and from the result, including an inherited/surviving field. - Application code owns opening/interpreting the resource and any qualified IDs. -4. Add tests for final values, presence, actual source placement/coordinates, - resource context, and expected conflict behavior. Link maintained examples - from the consumer guide; add a small executable root example if useful for - discovery without duplicating the complete scenario. - -Validated with `go test ./examples/consumers -count=1`, -`go test . -run '^Example' -count=1`, and `./scripts/check.sh` (go1.26.8 -linux/amd64); all passed, including local documentation links. - -`Example_inputDestination` demonstrates a literal mounted mapping path and an -ordinary root input without consumer-side parsing or merging. -`LoadCollectionBundle` and `TestCollectionBundleAssemblesMountedPeersAndResources` -exercise prompt/profile peer sources, imported collection metadata with an -ordinary version label, main-owned schema-version checking, local sibling -inheritance, and a higher-tier prompt version-only change that retains the rest -of its body. The resolver and `ReadCollectionPromptContent` follow direct and -inherited `content_file` provenance to the declaring native-filesystem context. -The test checks final values, explicit presence, source destinations and authored -coordinates, relative resources, and the inherited field's origin. -`TestCollectionPeerPromptConflictsRemainStrict` preserves expected conflict -behavior. The examples are linked from the consumer adoption guide. Done: simple -and representative consumers substantiate the same model without a compensating -structural pass. - -## Stage 12 — Reconcile documentation and audit the complete implementation - -Status: complete. Scope: final integration audit and evidence, not release work. - -1. Update README navigation, consumer guidance, the component overview, and - development reading/test maps. Add ADR 0011 to navigation. Update architecture - policy only as needed to recognize placement within existing assembly and - source ownership, linking precise behavior to the configuration contract. - Do not change unrelated policies, deferred boundaries, or published notes. -2. Audit every resolved decision, roadmap behavior, and request acceptance row - against implementation and tests. Record the corresponding test names here; - for reused coverage explain the behavior it proves. Do not mark complete - based on green tests that do not exercise mounting. -3. Review the complete baseline-to-candidate diff for accidental strengthening: - extra naming rules, namespace uniqueness, main-only restrictions, changed - merge/version semantics, invented source-read ordering guarantees, new limits, - or expanded secret policies. Remove temporary helpers/unsupported branches - left by staged integration. Confirm original source coordinates remain real. +1. Reconcile `docs/config.md`, declaration comments, consumer guide, component + overview, and development reading/test maps. Change only affected material. + Distinguish input entry placement and per-import effective placement; remove + unqualified uniform-inheritance claims. Add ADR navigation. Update architecture + policy only as needed to recognize the extension and link exact behavior to + its canonical contract. +2. Map each relative-import request row and roadmap behavior to specific tests + or examples here. Include root/layered loads, host/native acquisition, literal + keys, parser failures, peer/glob isolation, composition/version ownership, + failure records, resources, disclosure/history/diffs, accumulated limits, and + empty/absent contributions. Explain reused evidence; header rows stay deferred. +3. Review the baseline-to-candidate diff for accidental strengthening: extra + naming rules/caps, weakened containment/repetition, root resets, shifted + callbacks/version phases, error-order promises, header processing, or expanded + merge/secret semantics. Check explicit per-document traversal and the absence + of a uniform post-traversal source overwrite. 4. Run `./scripts/check.sh` and - `GOTOOLCHAIN=local GOPROXY=off go test -race ./...`. Review source-kind and - placement ownership coverage, error disclosure, complete-on-return handling, - and root/private boundaries. Record commit, Go version, results, and any - limitations. No release command, CI waiting, benchmark, or downstream upgrade. -5. Mark this plan and the roadmap implemented only when code, public examples, - and owning contracts agree. Retain completed planning evidence until separately - authorized release preparation. + `GOTOOLCHAIN=local GOPROXY=off go test -race ./...`. Record revision, Go version, + commands, results, and limitations. Check links and root/private boundary + coverage; no performance claims or new release gates. +5. Mark this plan and the relative-import roadmap complete only when code, tests, + maintained examples, and canonical docs agree. Preserve the broader request's + unfinished header proposal. Retain completed records until separately + authorized release preparation; no release/downstream upgrade is implied. -Audit evidence for the approved decisions and request acceptance surface: - -| Behavior reviewed | Evidence and what it proves | -| --- | --- | -| Root-owned `Input.Destination` and `SourceInfo.Destination`; detached conversions and publication | `TestSourceInfoDestinationConversionsAndCopies`, `TestFacadeFailedLoadExposesDetachedSourceDestination`, and `TestFacadeMountedMainAndUnderlayInspectionResourcesAndDiff` verify root/engine conversion, error records, and returned record detachment. `TestPublicFacadeBoundary` and `TestDependencyImportBoundary` verify no engine types cross the facade. | -| Literal mapping keys, parsed numeric keys, reserved structural tokens, and invalid-path preflight | `TestNormalizeDestinationUsesLiteralMappingKeys`, `TestNormalizeDestinationRejectsIndicesAndReservedKeys`, and `TestLayeredLoadPreflightsDestinationsBeforeReadingSources` cover mapping-only normalization and rejection before reader consumption; `TestFacadeDestinationRootEmptyMappingNoSourceAndInvalidPaths` verifies the public error boundary. | -| Placement of acquired bodies, empty mappings versus absence, imports, all source kinds, physical identity, and authored coordinates | `TestFacadeInputDestinationsAcrossSourceKinds` covers host/native/bytes/reader/mapping sources; `TestFacadeSameFragmentMountsAtSeparateCollectionDestinations` proves independent public collections can retain the same local key. `TestLayeredImportOnlyInputMaterializesDestination`, `TestLayeredHostImportsInheritInputDestinationTransitively`, `TestLayeredNativeFilesystemImportsInheritInputDestination`, and `TestLayeredDestinationsDoNotChangeRepeatedSourceIdentity` cover inherited import placement and unchanged identity. `TestPlaceDocumentWrapsEmptyMappingAndPreservesSourceCoordinates`, `TestPlaceDocumentPreservesAuthoredEntryCoordinates`, and `TestLayeredDestinationDiagnosticsUseEffectivePathsAndAuthoredLocations` distinguish fallback wrapper locations from authored coordinates. | -| Strict composition, explicit-wrapper equivalence, precedence, empty values, and domain `version` overrides | `TestLayeredDestinationStrictCompositionBoundaries`, `TestLayeredDestinationMatchesExplicitlyWrappedInput`, `TestEmptyMountedMappingRetainsLowerChildren`, and `TestLayeredDestinationOverlayRetainsOrdinaryValueSemantics` prove existing group and overlay semantics are retained; the latter includes ordinary field-only updates rather than whole-record replacement. | -| Main-owned version checks and imported, underlay, inheritance, overlay, CLI, and ancestor protection | `TestLayeredDestinationChecksVersionOnceOnComposedMain`, `TestLayeredDestinationVersionClaimsUsePlacedApplicationPaths`, `TestLayeredImportedVersionClaimsUseEffectiveDestination`, and `TestLayeredMountedVersionProtectionCoversInheritanceAndUpperTiers` cover effective paths, one main check, protected-path claims/ancestors, and nonclaiming mapping ancestors. `TestLoadVersionDestinationTypesKeepOrdinaryDecoding` preserves exact configured-path conversion and ordinary nested decoding. | -| Final-shape sibling inheritance, no cross-collection lookup, one lifecycle, and failure without a usable partial result | `TestLayeredDestinationInheritanceUsesFinalSiblingScopes`, `TestLayeredDestinationInheritanceDoesNotSearchOtherCollections`, `TestLayeredDestinationLifecycleAndSensitiveInspectionUseFinalShape`, and `TestLayeredDestinationDecodeFailureReturnsNoResultOrLaterCallbacks` exercise these behaviors. Reused inheritance, lifecycle, and callback tests cover generic behavior that destination placement does not alter. | -| Effective paths, presence, provenance/history, safe rendering, sensitivity, bilateral diff, and source-relative resources | `TestLayeredDestinationsRetainOriginsHistoryAndDetachedRecords`, `TestLayeredDestinationLifecycleAndSensitiveInspectionUseFinalShape`, `TestLayeredDestinationDiffUsesBilateralSensitivity`, `TestLayeredImportedInheritedValuesRetainResourceContexts`, and `TestFacadeMountedMainAndUnderlayInspectionResourcesAndDiff` connect mounted values to inspection. The imported-inheritance test specifically proves the inherited value keeps the declaring source's passive resource context. | -| Shared depth/node limits and unchanged root/absence accounting | `TestPlaceDocumentRootAndBounds`, `TestDestinationPlacementCountsAgainstSharedNodeBudget`, `TestMultipleMountedInputsSharePlacementCharges`, `TestImportedEmptyBodiesChargeEachDestinationWrapper`, `TestSelectedOverlayAndCLIUsePlacementNodeCharges`, and `TestNoSourceAndRootPlacementAddNoWrapperCharges` cover per-document and aggregate limits without adding a new limit class. | -| Maintained consumer usage and strict peer behavior | `Example_inputDestination`, `TestCollectionBundleAssemblesMountedPeersAndResources`, and `TestCollectionPeerPromptConflictsRemainStrict` verify the simple and representative collection examples against actual values, resources, source records, and conflict behavior. | - -The wider baseline-to-candidate review covered all 38 changed files (`6353598..2d8df22`): production changes are limited to the root facade fields/conversions, private input/import assembly and accounting, source record ownership, and the inheritance version-claim correction described above. The contract and tests do not impose identifier grammar, namespace uniqueness, main-only placement, source-read ordering, new budgets, nested version conversion, or expanded secret policy. The implementation wraps only acquired application bodies after processing source-root directives; placement does not change physical source identity, authored node locations, filesystem resolution, or later-tier semantics. Stage evidence above reuses existing general composition, resource, inheritance, version, lifecycle, sensitivity, and boundary tests where those behaviors are unchanged; mounted-specific cases are named separately. - -Completion record: audited source candidate `2d8df22dd1cb9fde8e60853da3e2260731acf2bb`. On `go1.26.8 linux/amd64`, `./scripts/check.sh` passed, including formatting, whitespace, documentation links, tests, vet, and build. `GOTOOLCHAIN=local GOPROXY=off go test -race ./...` also passed with dependency downloads disabled. No remaining implementation limitations were found; release preparation, CI, benchmark campaigns, and downstream upgrades remain separately scoped. - -Done: one complete layered load supports input destinations with coherent values, -diagnostics, inspection, limits, and source ownership across the approved surface. +Done: authors can declare immediate-parent-relative path/glob destinations in +existing import-capable loads with coherent values, provenance, bounds, and +ownership. Independent specification headers remain a separate future decision. ## Implementation owner map -Use graph tools to locate these symbols rather than assume line numbers: +Use graph discovery to confirm current symbols and locations before editing: -- Public input forwarding: `layered.go`, `records.go`, `conversion.go` - (source conversions), and existing facade tests. -- Private request and lifecycle: `internal/engine/layered.go`, `load_request.go` - (`loadInput`, `acquireUnderlayGroup`, `assembleLayeredInput`), `load.go` - (`executeLoadRequest`), and `load_input.go` (`assembleBaseInputTracked`). -- Directives and imports: `directives.go` (`splitImportDirectives`, - `fragmentVersionClaim`), and `imports.go` (`visitPath`). -- Shared document semantics: `compose.go`, `document_walk.go` - (`countInputNodes`), `path.go`, `parse.go`, and `value_operation.go` limits. -- Inspection: `metadata.go`, `history.go`, `explain.go`, `resource_context.go`, - `inheritance_origin.go`, `render.go`, and `diff.go`; source copies live in - engine `records.go`. Confirm current filenames through the component overview. +- `internal/engine/directives.go`: `importDeclaration`, + `parseImportDeclaration`, `parseImportDirective`, `splitImportDirectives`, + and source-local diagnostic construction. +- `internal/engine/imports.go`: `importTraversal`, + `loadImportedWithAccessTracked`, `walkDeclarations`, `visitPath`, and shared + accounting. `glob.go` owns physical matching and its ordering. +- `internal/engine/destination.go`: `normalizeDestination`, `placeDocument`, + `destinationWrapperNodeCount`, and source-destination assignment. +- `internal/engine/load_input.go`: `assembleBaseInputTracked`, early failures, + context handoff, and completed Mapping diagnostic remediation. +- Existing assembly/lifecycle: `load_request.go`, `load.go`, `compose.go`, + `inheritance_load.go`, and metadata/history/rendering/diff owners. +- Root inspection: `records.go`, `conversion.go`, `layered.go`, and existing + public destination/import tests. No new exported Go surface. +- Behavioral foundations: engine `imports_test.go`, `glob_test.go`, + `destination_import_test.go`, `destination_accounting_test.go`, + `destination_diagnostic_test.go`, `destination_provenance_test.go`, + `destination_integration_test.go`; root `facade_destination_test.go`; and + maintained consumer fixtures/tests. Reuse owners rather than duplicate suites. ## Open Questions -None required for implementation. The four policy choices are approved; this -plan selects API spelling, validation timing/error category, coordinate handling, -and accounting within them. Surface a newly discovered incompatibility or scope -change with evidence rather than resolving it by silently narrowing the feature -or strengthening an unrelated contract. +None required for this feature. Selected list syntax and existing placement +contracts resolve the public choices; this plan settles context, diagnostic, +and accounting details within them. Report a newly discovered incompatibility +with evidence and alternatives rather than adding a restriction or implementing +the separate source-header proposal. diff --git a/docs/roadmap/input-destinations.md b/docs/roadmap/input-destinations.md index fc84a68..e8bb58e 100644 --- a/docs/roadmap/input-destinations.md +++ b/docs/roadmap/input-destinations.md @@ -2,8 +2,9 @@ Status: implemented. This roadmap records the approved behavior and rationale for the [PromptKit feature request](promptkit-feature-request.md). The -[implementation plan](implementation.md) records the completed sequence and -audit evidence; the [configuration contract](../config.md#input-destinations) +completed implementation plan is preserved in Git history at +`315f464:docs/roadmap/implementation.md`, including its audit and remediation +evidence; the [configuration contract](../config.md#input-destinations) owns current behavior. ## Targeted end state diff --git a/docs/roadmap/promptkit-feature-request.md b/docs/roadmap/promptkit-feature-request.md index 7813d0e..751436d 100644 --- a/docs/roadmap/promptkit-feature-request.md +++ b/docs/roadmap/promptkit-feature-request.md @@ -1,10 +1,14 @@ -# PromptKit Feature Request: Configuration Input Destinations +# PromptKit Feature Request: Mounted Collections And Specification Headers -Status: consumer feature request; not accepted or implemented. +Status: input destinations are implemented on the ConfigKit development branch +(reviewed at `315f464`). Independent collection specification headers and relative +import destinations are requested additions; not yet accepted or implemented. ## Requested Capability -Provide a public API through which a consumer can select a destination mapping +Extend the public loading API so independently maintained collections can declare +and check their specification compatibility and describe relative import +destinations. Preserve the implemented capability to select a destination mapping path for each configuration input. The input's application content contributes beneath that path while retaining ConfigKit's normal composition, precedence, inheritance, validation, diagnostics, and inspection behavior. @@ -15,11 +19,12 @@ Configuration Fragments**, recorded in PromptKit's describes the public API needs and observable acceptance criteria. It does not prescribe ConfigKit's internal design or an implementation plan. -The reviewed public baseline is ConfigKit v0.7.1. The current -[layered-loading contract](../config.md#layered-loading) lets consumers choose -sources, import policy, filesystem context, and precedence groups, but does not -provide an input destination. Existing behavior remains authoritative until an -extension is adopted. +The original request targeted ConfigKit v0.7.1. The development branch now +supplies `Input.Destination` and `SourceInfo.Destination`, as documented in the +[input destination contract](../config.md#input-destinations). The placement +requirements below remain the baseline for the two additions. Current released +behavior and development-branch behavior must not be confused with the newly +proposed header and import syntax. ## Consumer Problem @@ -78,17 +83,13 @@ source processing back into PromptKit and complicate source attribution. PromptKit instead wants to select sources and destinations, then receive one final configuration through ConfigKit's supported loading lifecycle. -## Minimum Public API +## Implemented Placement API And Required Baseline ### Per-Input Destination -Allow a destination to be attached to each `Input` passed to `LoadLayered`. -One possible public spelling is an optional `Destination Path` field on `Input`. -The name and exact signature are suggestions; equivalent public API designs -are welcome. - -Illustrative consumer code using the proposed field, which does not exist in -v0.7.1: +The development branch provides `Destination Path` on each `Input` passed to +`LoadLayered`, matching the original request. The following partial consumer +example uses that implemented field, which was not available in v0.7.1: ```go promptInput := configkit.Input{ @@ -182,9 +183,9 @@ An input with imports enabled must be able to use its existing source-root destination. The directive remains structural configuration, not an application field below that destination. -For the minimum API, imports inherit their importing input's destination, -including transitive imports. Import paths continue to resolve relative to -their declaring source's filesystem context. A mounted document must not send +Without an explicit relative destination, imports inherit their importing +input's destination, including transitive imports. Import paths continue to +resolve relative to their declaring source's filesystem context. A mounted document must not send its imported application fields back to the configuration root accidentally. Existing opt-in, containment, missing-input, cycle, and repeated-source behavior @@ -220,9 +221,11 @@ application paths, rather than reserving the spelling `version` in every source. Protection must remain valid with imports, inheritance, overlays, and explicit CLI overrides. -PromptKit needs one main-owned specification check with the existing lifecycle. -It does not need main mounted away from the root, integer-to-string conversion -for every nested `version`, or separate compatibility checks for every fragment. +Retain the main-owned specification check with its existing lifecycle. The new +collection-header checks below are explicit, separate source compatibility +checks; they do not authorize contributions to the main-owned version path. +PromptKit does not need main mounted away from the root or integer-to-string +conversion for every nested ordinary `version` field. ### Typed Loading, Diagnostics, And Inspection @@ -263,20 +266,156 @@ and resource-access behavior. Destinations must participate in documented load limits without creating a way to bypass them; this request does not prescribe new limit values or their accounting machinery. -## Optional Follow-Ups, Not Prerequisites +## Requested Addition: Independent Collection Specification Headers -**Import destinations in YAML.** A destination on an import directive could let -publishers describe assembly in configuration rather than Go. Proposal 3 -recommends destinations relative to the importing document's destination, with -omission retaining that destination. This is useful, but per-input placement -through the public API is sufficient for initial PromptKit adoption. No new -directive spelling is selected by this request. +### Consumer Need And Public API -**Independent specification headers.** A collection entry document might later -declare its own supported specification version. That needs a distinct contract -for checking the header and determining its role in the composed configuration. -Mounting collection release metadata does not supply this capability. Keep it a -separate request if PromptKit decides it is necessary. +Allow an application to attach an opt-in source specification rule to a selected +collection entry `Input`. PromptKit would configure the source-local header path +as `version` and supply its supported-specification policy. ConfigKit owns +checking the declaration and delivering structured diagnostics within the same +`LoadLayered` operation. This must not require PromptKit to open, parse, or load +collection manifests separately. + +Reuse the public version vocabulary where appropriate: the checker should be +able to distinguish absent, null, string, and strict decimal-integer declarations +and receive their text without imposing SemVer. For PromptKit specification 1, +`version: 1` and `version: "1"` can express the same supported identifier. +PromptKit decides which declarations it accepts, including whether a missing +header is an error. Exact API names and how the source rule relates to the +existing `VersionRule` type are ConfigKit design decisions. + +This is a separate rule from `Definition.Version`, which continues to describe +the main-owned application specification. It checks a source's declared format, +not its complete domain schema. Domain validation still runs on final effective +configuration, not once per collection or fragment. + +The minimum API must support several collection entry inputs in one load, each +with a destination and an explicitly assigned source-header policy. Source +selection determines which documents are entries. Neither a filename nor the +mere presence of a field named `version` automatically enables header checking. +No YAML-selected executable checker or general source-validation callback is +requested. + +### Header Scope And Payload + +Recommend one required specification declaration per selected collection entry, +with its ordinary imported fragments authored under that declared specification. +Do not require a repeated header in every prompt/profile fragment. Importing a +fragment does not give it an independent header rule; in particular, its ordinary +release or prompt `version` must not be consumed as a specification header. + +For an explicitly configured entry, check its own declaration independently of +other inputs and precedence layers. Another source cannot supply a missing +header, and a higher-priority override cannot conceal an unsupported declaration. +Any rejected entry fails the whole load with no usable partial result, even if +its payload would subsequently be superseded. Reusing a physical source across +allowed separate tiers retains existing source-reuse semantics; this request +adds no source-uniqueness policy. + +After an entry header is accepted, recommend consuming it as structural source +metadata: it does not contribute at the mounted application path. For example, +entry `version: 1` must not become `collections.weatherreporter.version`. The +collection release label can be contributed separately as ordinary payload. +This distinction also prevents unrelated collection specification declarations +from conflicting during strict composition. + +This consumption applies only to the explicitly selected source header. It +must not remove nested versions, imported metadata, or the main application's +existing version field. The API should make the distinction between a consumed +source header and a retained main declaration explicit; it must not silently +change existing `Definition.Version` behavior. + +### Diagnostics And Inspection + +Expose the checked declaration and its source-local location through supported +source inspection, or equivalent public metadata. Consumers should be able to +identify the source, header path, and accepted declaration without rereading +files. Preserve the normal distinction between authored input evidence and +rendered effective application configuration: a consumed header is evidence of +source compatibility, not an effective domain field. + +Header failures and warnings should use ConfigKit's structured diagnostics and +normal disclosure rules. Report the actual entry source and header location, +or a source-location fallback when the header is absent; do not attribute them to the +unrelated protected root field or invent an effective payload field. The +source's destination remains inspectable. Exact diagnostic codes and inspection +types are left to ConfigKit. + +## Requested Addition: Relative Import Destinations + +Extend the public YAML import directive so a `path` or `glob` import can specify +a relative destination as literal mapping-key segments. An illustrative spelling +is `destination: [prompts]`; the exact directive field name remains a proposal. + +The public behavior should be: + +- The importing document has an effective destination established by its input + or its own import. An explicit import destination appends key segments to that + destination. Omission or an empty list retains the importing destination. +- Every file matched by a glob receives the same declared relative destination. + Transitive imports are relative to their immediate importing document's + resulting destination, not always to the original entry destination. +- Filesystem paths still resolve relative to the declaring file, with existing + containment rules. Logical placement and physical file resolution are + independent; there is no root-reset or parent-traversal meaning in destination + key segments. Literal keys follow the same rules as `Input.Destination`. +- Imports retain their existing strict-composition tier. Import order and + destination declarations do not create precedence or permit replacement. +- Existing optionality, repeated-source, cycle, source-kind, and ownership rules + remain intact. A destination does not authorize importing one physical file + twice in a group. Existing source-root directive and reserved-key rules apply. +- `SourceInfo.Destination` reports each import's resulting effective destination. + Effective paths, original locations, resource contexts, protected version + paths, sensitivity, and error behavior retain the placement baseline above. +- Invalid directive shapes fail through the normal structured error boundary; + destination fields must not be silently ignored. + +This is declarative access to the existing placement capability. It does not +request recursive glob syntax, implicit directory scanning, namespace inference, +or a new composition strategy. + +## Combined Collection Entry Example + +With both additions, an entry document selected by the application with a source +header rule and destination `[collections, weatherreporter]` could contain: + +```yaml +version: 1 +configkit: + imports: + - path: metadata.yml + - glob: prompts/*.yml + destination: [prompts] + - glob: profiles/*.yml + destination: [profiles] + - glob: backends/*.yml + destination: [backends] +``` + +This is proposed syntax, not currently executable configuration. Each required +glob assumes matching files; collections can omit unused categories or use +existing optional-import behavior. The application still selects and provisions +the collection and assigns its namespace. ConfigKit does not discover it. + +The entry's `version: 1` is checked and consumed. Its `metadata.yml` can contain +`version: "2.4.0"`, retained as the collection's ordinary release label because +that import has no independent header rule and inherits the collection +destination. Prompt fragments retain local mapping keys and optional prompt +versions, and are placed beneath the collection's `prompts` mapping. The main +application can independently retain its own `version: 1` declaration. + +Thus publishers can describe their collection layout, authors can keep compact +fragments, and operators can compose several independently checked collections +without application-side source rewriting. These checks establish declared +specification compatibility, not package authenticity, release integrity, or +proof that every fragment was authored correctly. + +## Deferred And Excluded Work + +**Identity-based list composition.** Keep this deferred. Proposal 3's local +mapping keys already identify each installed resource; the two requested +additions do not require a different representation or sequence merge policy. **Cross-collection inheritance.** Nested collection profiles are not immediate siblings across collections. Current sibling inheritance remains sufficient for @@ -312,8 +451,20 @@ Evaluate the extension through supported public loading and inspection APIs: | Mounted validation error or secret field | Effective paths, physical locations, and existing disclosure rules agree | | File, native filesystem, byte, reader, or mapping input with equivalent content | Equivalent application values, subject to existing source contracts | | Unsupported destination or failed load | Normal structured failure, no usable partial result | +| Several collection entries with supported specification headers | Each declaration is independently accepted; payloads compose normally | +| Missing, null, malformed, or unsupported entry header | ConfigKit reports structural/type errors or invokes the configured version policy as appropriate; rejection fails the whole load | +| Unsupported entry superseded by a higher layer | Compatibility failure remains visible and fails loading | +| Consumed entry header plus imported release metadata | Header is inspectable as source evidence; only the release label becomes the collection's ordinary version field | +| Ordinary imported fragment containing `version` without a header rule | Field remains ordinary payload and is not independently consumed or checked | +| Relative import destination omitted or empty | Existing inherited-destination behavior | +| Entry at `[collections, weather]`, import at `[prompts]`, nested import at `[extras]` | Nested contribution appears beneath `[collections, weather, prompts, extras]` | +| Glob import with a relative destination | Every matched contribution uses that destination and composes strictly | +| Relative import destination with source-relative resource | Effective configuration path changes; resource base remains the declaring source | +| Load without source-header rules or relative import directives | Existing loading and main VersionRule semantics remain unchanged | -The minimum usable outcome is a consumer that selects collection sources and -destinations, performs one ordinary layered load, and receives final typed -configuration with reliable diagnostics and inspection. It should need no +The requested outcome is a consumer that selects collection entry sources, +destinations, and specification policies, performs one ordinary layered load, +and receives final typed configuration with reliable diagnostics and inspection. +Collection entries describe their own relative import placements, and unsupported +source specifications fail independently of payload precedence. It should need no consumer-side source rewriting, generic merging, or provenance reconstruction. diff --git a/docs/roadmap/relative-import-destinations.md b/docs/roadmap/relative-import-destinations.md index 93281ed..872d7cc 100644 --- a/docs/roadmap/relative-import-destinations.md +++ b/docs/roadmap/relative-import-destinations.md @@ -1,10 +1,11 @@ # Relative Import Destinations Roadmap -Status: planned; implementation has not started. Execute the stages below in -order. This roadmap addresses only the relative-import-destination addition in +Status: planned; syntax selected and implementation has not started. The +[implementation plan](implementation.md) owns sequencing and completion evidence. +This roadmap addresses only the relative-import-destination addition in the [PromptKit request](promptkit-feature-request.md#requested-addition-relative-import-destinations). Independent source specification headers are deferred for reconsideration after -this work is implemented; they are not a prerequisite or part of these stages. +this work is implemented; they are not a prerequisite or part of this feature. ## Targeted end state @@ -114,105 +115,6 @@ Reviewed baseline: `315f464`, with input destinations implemented. The The change extends traversal and directive parsing. It should reuse existing placement and assembly rather than introduce a second merge or validation model. -## Ordered implementation plan - -### 1. Document the selected syntax and semantic extension - -Use the Selected Design Decision below to specify valid shapes, literal key -handling, and structured failures. Preserve existing `path`/`glob` and `optional` -behavior. -Validate declared destination syntax even when an optional import has no match; -optionality suppresses missing input, not malformed directives. - -Record the extension to ADR 0011's inherited-destination model in a new ADR -without rewriting the accepted decision. Distinguish the new declarative syntax -from unchanged input placement and version ownership. Review compatibility -under the release policy without choosing or publishing a release in this work. - -Completion: the syntax and parent-relative semantics are explicit, with source -specification headers still deferred and no additional merge or namespace rules. - -### 2. Parse destinations and carry effective placement through traversal - -Extend private import declarations and parser validation with the selected -relative destination representation and useful declaration locations. Reuse -existing key validation rather than maintaining a competing path convention. - -Compute each child's effective destination from the immediate parent's placement. -Pass that context through path imports, glob expansion, and recursive traversal. -Explicit per-call state is a straightforward implementation option; the public -contract need not prescribe a parameter, stack, or allocation layout. Ensure -nested placement cannot leak into siblings, subsequent glob matches, or inputs. - -Use the resulting destination when placing the body, checking effective version -claims, accounting for limits, and creating source records. Remove or narrow -uniform post-traversal source-destination assignment. Retain original physical -identity and resource contexts; do not include destination in repetition keys. - -Completion: nested and sibling imports, glob matches, and source records all use -the right effective destination, with structured errors and existing bounds. - -### 3. Verify integration with assembly and inspection - -Check that placed source applications feed existing strict composition, tier -precedence, inheritance, and final typed loading. Confirm conflicts report the -effective path and contributing physical locations, including imports that -collide with explicitly wrapped input or a destination ancestor. - -Verify protected version claims after destination accumulation, and ordinary -version payload away from the protected path. Confirm history, sensitivity, -rendering, and diffs use placed data without reconstructing placement in callers. -Exercise inherited and surviving lower-tier resource references through existing -source-context APIs. Preserve detached source records and existing failure -behavior; do not add promises about collecting every error or exact failure -ordering merely to simplify tests. - -Completion: imports with explicit destinations agree with equivalent existing -placement for application behavior, while actual source attribution stays intact. - -### 4. Add acceptance coverage and consumer guidance - -Use parser tests for declaration shape, engine tests for traversal and placement, -and public tests/examples for complete consumer workflows. Reuse existing tests -where they already protect unchanged behavior. Cover the following distinct risks: - -| Scenario | Evidence required | -| --- | --- | -| Omitted destination and `[]` | Existing inherited placement, including root imports | -| Entry, child, and grandchild destinations | Placement accumulates from the immediate importer | -| Nested import followed by a sibling; multiple glob matches | Child state does not leak to peers | -| Literal slash, dot, numeric-looking, and empty keys | Existing mapping-key meaning is preserved | -| Invalid shapes and reserved keys, including optional unmatched imports | Structured directive failure with a real declaration location | -| Disjoint, overlapping, and ancestor-related destinations | Existing composition conflicts and tier precedence | -| Same physical source selected at different destinations in a group | Existing repetition/cycle policy is retained | -| Mounted import targeting a protected version path | Existing ownership checks use the accumulated path | -| Ordinary version payload elsewhere | No new checking, coercion, or consumption | -| Inheritance, overrides, and resource-relative fields | Effective paths and original resource bases agree | -| History, classified values, and diffs | Existing provenance and disclosure rules remain effective | -| Accumulated depth, wrapper nodes, empty bodies, and absent optional sources | Existing accounting and contribution behavior | -| Host/native filesystem imports and supported entry source forms | Placement is independent of acquisition kind | -| Public source inspection and load failures | Accurate effective destinations and detached records | - -Add an executable collection-entry example that imports metadata and mounts -prompt/profile fragments. It must use no source header checker or consumer-side -parsing, merging, or provenance reconstruction. Demonstrate ordinary root loading -as well as a representative layered mounted entry without duplicating all cases. - -Update the owning configuration contract and consumer guide as behavior lands; -update source-record declaration documentation and internal overview only where -their descriptions change. Keep the header proposal deferred for later review. - -Run focused tests, then the everyday check and appropriate ownership race checks -from the [development guide](../development.md), following the -[testing policy](../policy/testing.md). Validate documentation links. No independent -performance benchmarks are part of this roadmap. - -Completion: the relative-import acceptance scenarios in the PromptKit request -are covered, the combined workflow works without source headers, validation -passes, and implemented documentation matches the behavior. Source specification -headers can then be reconsidered as a separate feature; their implementation is -not required to complete this roadmap. - ## Selected Design Decision ### YAML destination representation diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index ad7e4f6..5272bad 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -2,7 +2,8 @@ Reviewed `d3d468a..945e111` against the approved [input-destinations roadmap](input-destinations.md), -[implementation plan](implementation.md), and +input-destination implementation plan (preserved at +`315f464:docs/roadmap/implementation.md`), and [ADR 0011](../adr/0011-input-destinations.md). The root-owned destination fields, placement before strict composition,