42 KiB
Implement configuration input destinations
Status: complete. Stages 1–12 are implemented and audited. The
feature roadmap owns the approved behavior and rationale; the
consumer request
supplies the public acceptance scenarios. This document owns execution and
completion evidence. Planning baseline: 6353598.
Working instructions
- Start each stage with
AGENTS.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.shbefore 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.
Resolved implementation decisions
- Add root-owned
Input.Destination PathandSourceInfo.Destination Path, mirrored privately in engine input/source records. ExtendloadInputand explicit root/engine conversion and cloning. No new loading entry point, public wrapper type, option, or origin field is needed. OrdinaryLoadcontinues to supply root placement. - 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:/0means the key0, 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. - Reject destination segments equal to
configkitorextends: placement would introduce a reserved mapping key with a mapping value. Substrings such asmyextendsare ordinary keys. This preserves the approved structural rules rather than adding an application naming policy. Source-root import directives are still processed before placement. - Validate destination shape/reservations for all declared inputs during
grouped option preflight, before reading any source. Reuse
CodeOptionsInvalidfor 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 onNoSourcecontributes no nodes, source record, or budget charges. No extra error type or exact message contract is introduced. - 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.
- 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. - 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
NoSourceremain absent. Empty source text remains the existing invalid document, not an empty mapping. VersionRule.Pathstays 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 domainversionfields 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.- 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. - 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.
- 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 additional2 * segmentCountsynthetic 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. - 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.
Stage 1 — Record the decision and capture the baseline
Status: complete. Scope: decision record and evidence, no feature code.
- 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.
- 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. - Write
docs/adr/0011-input-destinations.mdafter 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. - Record the compatibility assessment under the release policy: adding fields
preserves zero-value/keyed-literal use, but callers using unkeyed literals
for
InputorSourceInfomust migrate to keyed literals. Treat the feature as minor-release work; select a version and write its note only during separately authorized release preparation.
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.
Coverage located for later destination work:
- Root and equivalent source loading:
TestEquivalentSourceFormsPreserveInputSemantics(facade_equivalence_test.go) andTestFacadeLayeredZeroUnderlaysMatchesOrdinaryLoad(facade_layered_test.go). - Strict underlays and group budgets:
TestGroupedLoadStrictConflictsRepetitionAndBudgetsandTestGroupedLoadPrecedenceSourceOrderAndSingleLifecycle(internal/engine/load_request_test.go). - Version ownership and imported claims:
TestLoadRejectsImportConflictsAndFragmentVersions(internal/engine/imports_test.go) and version-path coverage ininternal/engine/load_test.go. - Repeated physical sources:
TestRepeatedImportsAcrossTiersAndReaderConsumption(facade_equivalence_test.go). - History and source contexts:
TestUnderlayHistoryRetainsLaterMappingContributors(facade_underlay_origins_test.go) andTestFacadeSourceContextsFollowOriginsWithoutQueryIO(facade_resource_context_test.go). - Detached records:
TestLoadMetadataReflectsDefaultsInputAndDetachedRecords(internal/engine/load_test.go) andTestMetadataQueriesReturnDetachedRecords(internal/engine/metadata_test.go).
The decision is recorded in ADR 0011.
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.
Stage 2 — Add private destination normalization and wrapping
Status: complete. Scope: pure private mechanics with bounded unit tests.
- 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.
- Validate invalid paths, explicit indices, and exact reserved tokens. Normalize parsed numeric tokens into keys, preserving literal text and pointer escaping.
- 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.
- 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.
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.
Stage 3 — Integrate private non-import input placement
Status: complete. Scope: engine request plumbing and ordinary acquired bodies.
- Add destination fields to engine
Input,loadInput, andSourceInfo. Preserve ownership through engineLoadLayeredrequest construction,cloneSourceInfo, and source-record copies. Keep the root facade unchanged. - Extend grouped preflight to validate/normalize destinations before source
reads. Use the existing diagnostic accumulator and options-invalid category.
Ordinary
Loadsupplies root placement through its existing request adapter. - Thread placement into
assembleBaseInputTrackedwithout confusing rawparsedSourcewith effectiveassembledInput.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. - 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.
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.
Stage 4 — Carry placement through import acquisition
Status: complete. Scope: source-local directives and placed imported applications.
- Thread a normalized destination through
loadImportedDocumentsTracked,loadImportedWithAccessTracked, andimportTraversal, retaining root defaults for current private callers. Place the selected body's application content aftersplitImportDirectives; do the same for every imported body. - Set placement on selected/imported source records, including error records
once a source has been acquired. Keep
ImportedFromat the physical directive. Run importedfragmentVersionClaimagainst placed bodies and retain placed bodies instate.documentsbeforecomposeDocumentsbuilds applications. - 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.
- 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.
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.
Stage 5 — Complete strict tiers and main version ownership
Status: complete. Scope: assembly and version interactions, not a new merger.
- Review
acquireUnderlayGroup: version checks must use placed content, and documents taken fromacquired.composition.applicationsmust already be placed. Recompose strict peers with ordinarycomposeDocuments; preserve per-source applications, origins, UnderlayIndex, and input accounting. - In
executeLoadRequest, main's version check uses its placed main/import composition at the existing point.assembleLayeredInputrecursively 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. - 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.
- 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.
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.
Stage 6 — Reconcile diagnostic coordinate systems
Status: complete. Scope: useful paths without fictional source locations.
- 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.
- 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.
- 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.
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.
Stage 7 — Complete shared placement accounting
Status: complete. Scope: resource bounds with no new public limit system.
- Wire Stage 2's prechecks and synthetic-node charges into both tracked ordinary
acquisition and import traversal, using
importAccountingand current limit structures. Charge each source body once, including empty import bodies. - 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.
- 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.
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.
Stage 8 — Preserve provenance, history, and source resource contexts
Status: complete. Scope: engine inspection and retained evidence.
- 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. - 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.
- 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.
- 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.
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.
Stage 9 — Verify final inheritance, sensitivity, and lifecycle integration
Status: complete. Scope: complete private engine behavior before facade exposure.
- 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.
- 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.
- 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.
- 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.
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.
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.
- Add
Input.Destination PathandSourceInfo.Destination Pathto root types. ExtendtoEngineInput,fromEngineSourceInfo,toEngineSourceInfo, and all source publication paths with owned conversion. Run existing public/import boundary tests; expose no engine nodes, aliases, or bridge methods. - 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.
- 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.
- 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.
- Add a minimal mounted-fragment example using
Input.Destinationin an ordinary layered load. Show literal keys and root-default compatibility without introducing consumer parsing or generic merge helpers. - Add one representative collection assembly under
examples/consumers: peer prompt/profile fragments, collection metadata with ordinaryversion, 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. - 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.
- 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.
- 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.
- 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.
- 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.
- Run
./scripts/check.shandGOTOOLCHAIN=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. - 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.
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.
Implementation owner map
Use graph tools to locate these symbols rather than assume line numbers:
- 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), andload_input.go(assembleBaseInputTracked). - Directives and imports:
directives.go(splitImportDirectives,fragmentVersionClaim), andimports.go(visitPath). - Shared document semantics:
compose.go,document_walk.go(countInputNodes),path.go,parse.go, andvalue_operation.golimits. - Inspection:
metadata.go,history.go,explain.go,resource_context.go,inheritance_origin.go,render.go, anddiff.go; source copies live in enginerecords.go. Confirm current filenames through the component overview.
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.