diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index ffb93ec..72d986c 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,296 +1,737 @@ -# Import Discovery And Facade Simplification Implementation Plan +# Interface Contract Remediation Implementation Plan -Status: complete. -Baseline: `bb5540b62e382106d59678e2edb7655acfd5c960`. -Audience: a Luna coding agent implementing the stages sequentially. +Status: pending. All stages below remain unimplemented. +Baseline: `f6d54a094a2b5ada5748686620659399dce7ebf0`. +Audience: a Luna coding agent executing the stages sequentially. ## Scope And Execution -Implement **C03** and **F07** from the -[internal-boundary roadmap](internal-boundaries.md). That document owns the target -state and preservation requirements; this plan owns concrete private choices, -steps, validation, and progress. The preceding 29-finding remediation sprint is -complete. Its implementation record remains at -`bb5540b:docs/roadmap/implementation.md`; this plan does not reopen it. +Implement all four findings in the [interface audit](interfaces.md) and the +selected shared-history architecture in the +[interface remediation roadmap](interface-remediation.md). The roadmap owns +the target and policy choices; this plan selects private representations, +handoffs, migration steps, tests, and completion checks. The previous completed +C03/F07 plan is preserved at `f6d54a0:docs/roadmap/implementation.md`. -Read `AGENTS.md`, [agent policy](../policy/agents.md), the [development -guide](../development.md), and applicable architecture, testing, and documentation -policies. Use graph-first discovery and verify actual callers before deleting -helpers. Preserve unrelated work. +This is one end-to-end sprint. Intermediate stages and commits may fail to +compile. Do not create temporary adapters, parallel implementations, or extra +copies just to make intermediate stages green. Record deferred checks and run +them as soon as their surface is buildable. Commit focused nonempty units under +the [agent policy](../policy/agents.md); update each stage's status and actual +validation here. Do not claim completion based only on checked-off stages. -This is one end-to-end sprint. Intermediate stages may fail to compile, especially -the coordinated engine/facade cutover in Stages 2–3. Do not create adapters, -aliases, duplicate paths, or extra abstractions solely to make intermediate -stages green. Run focused checks once their affected surface is buildable; record -pending checks and finish them before final acceptance. Commit focused nonempty -units under repository policy and record stage status, actual validation, and -known commit identifiers here. Completion requires the integrated result, not -just checked-off stages. +Read `AGENTS.md`, the [development guide](../development.md), and applicable +[architecture](../policy/architecture.md), [testing](../policy/testing.md), and +[documentation](../policy/documentation.md) policies. Use graph-first discovery +and inspect actual callers before removing private members. Preserve unrelated +work. Existing contract owners are [Go paths](../../path.go), +[metadata](../config.md#layered-metadata), +[resolution](../config.md#recorded-application-resolution), +[explanation](../config.md#historical-value-explanation), and +[composition](../config.md#strict-document-composition). ### Boundaries -- Preserve public root-owned declarations and signatures, YAML syntax, loading - semantics, ordinary/layered differences, callback order, diagnostics, source - identity, inspection, confidentiality, and ownership. -- Preserve glob literal-versus-discovered rules and directory/glob differences. - Keep completed-link reuse, directory failure phases, containment, and existing - accounting. This is not a discovery algorithm or permission-policy change. -- Keep `resolvedImportPolicy`, registration compilation, normalized request - responsibilities, and conversions with real ownership or domain meaning. - Simplification is limited to defaults transport and placement construction. -- Add no dependencies, caller controls, caches, limits, background work, release - gates, or performance promises. Do not publish a release, update consumers, or - revise accepted ADR decisions. +- Keep root-owned public signatures, record fields, path syntax, source ordering, + composition/precedence, inheritance, decoding, CLI assignment, and callback + order. Correct the four reported defects without a general API redesign. +- Preserve the distinct metadata and explanation projections. In particular, + metadata retains composite definitions and specific resolution attribution; + explanation retains raw contributions, typed reconciliation, and net grouped + resolution events. They do not need identical record lists. +- Preserve explicit zero/false/empty/null, equal-valued writes, source/resource + attribution, historical sensitivity, and detached output records. Shape-aware + attribution must not narrow pointer-conservative redaction. +- Preserve schema-path diagnostics on `IsExplicit`, silent failed `InputInfo` + queries, helper validation, callback guards, and net-change resolution auditing. + Do not track transient callback mutations or infer identity across sequence + moves. +- Keep history-budget rejection before effective secret lookup and application + validation, using the existing quota and error code. Do not add limits, + dependencies, caches across loads, background work, public events, ordering + options, release gates, or performance promises. +- Do not publish, update consumers, or change accepted ADR decisions. This is a + private ownership refactor implementing existing public decisions. -### Selected Ownership Model +## Selected Private Design -Use the existing engine `ImportDefaults` name and its exported `Required`, -`Follow`, `Hidden`, `Recursive`, and `Pattern` fields as the sole engine -input-defaults type. Root `ImportDefaults` stays separately defined. Root -conversion maps the fields without cloning them; the public loading wrappers -immediately enter engine preflight. `loadSettings` takes the per-load snapshot -before acquisition or callbacks, as it already does. The normalized request and -acquisition policy then borrow that load-owned read-only value. +These choices settle the implementation design. Ordinary helper/file naming may +be adjusted for cohesion; the evidence ownership and selection rules must remain. +Do not defer choosing a different history architecture to an implementation stage. -Declaration resolution reads the owned defaults and retains its existing copies -of selected pattern/exclusion slices and destinations in `resolvedImportPolicy`. -This separates presence-aware load input from independently owned effective -declaration policy. No public copy-count or thread-safety guarantee follows. +### One Model, Owned Evidence, And Two Projections -For placement, expose the engine's existing enum as `PlacementMode uint8` with -`PlacementModeMapping` and `PlacementModeSequenceItem`, and expose placement -fields on engine input/options records for direct construction. These remain -internal-package implementation surfaces. Root types stay root-owned; direct -casts preserve unknown values for existing preflight validation. +Add `history_model.go`, `history_select.go`, and phase-specific files under +`internal/engine`. Use a concrete `historyBuilder` during loading and a concrete +`historyModel` after preparation; no interface hierarchy, generic event bus, +serialization format, or public API is needed. -### Validation Conventions +The builder owns one model under construction. The model contains: -Run from the repository root with an installed compatible Go toolchain and -dependencies already available. Use `GOTOOLCHAIN=local`, `GOPROXY=off`, and -`GOTELEMETRY=off`. Keep disposable artifacts outside the repository and do not -change dependencies for tooling. Focused expressions identify behavior owners; -include a newly named regression explicitly if needed. Reuse unchanged successful -checks. No timing, allocation, exact syscall, or helper-shape assertions are -acceptance criteria. +- The canonical baseline, pre-CLI typed checkpoint, post-CLI typed checkpoint, + and final projection, with the corresponding origin indexes where used. +- Ordered source `historyApplication` records and their sequence projections; + one owned inheritance-operation slice; ordered CLI applications; original + resolution snapshots; and replay groups referring to original snapshot IDs. +- Ordered phase groups and normalized semantic observations described below. + Groups refer to owned payloads by integer IDs rather than copying them. +- A pointer-to-concrete-shapes inventory and pointer-to-observation-ID index, + plus the existing prefix-index mechanism for enclosing/contained operations. + Pointer spelling is an index key, not a semantic identity. +- Eagerly built lookup/index state used by published queries. No query mutates + or lazily initializes the shared model. -## Stage 1 — Extract Patterned Glob Entry Preparation +Use these phase groups, in order: baseline; source contributions; inheritance; +pre-CLI reconciliation; CLI contributions; post-CLI reconciliation; resolution. +An inventory-only observation is not a public history event. Preserve phase and +producer order even for equal-valued contributions. -Finding: **C03**. Owners: `internal/engine/glob.go`, existing glob selection, -link, and directory failure tests. Status: **complete**. Validation passed: -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Glob|Directory|Link|Filesystem|Resource'` and `git diff --check`. +Keep `historyApplication`, sequence contribution descriptors, and +`inheritanceOperation` as useful private producer payloads. Their existing merge, +position-projection, and transfer algorithms remain authoritative. Move their +historical interpretation into this owner; do not rewrite configuration assembly +merely to produce a different inspection representation. -1. Add `prepareGlobEntry` beside the selector. Take the filesystem access, - base path, parent `selectedImportCandidate`, `fs.DirEntry`, pattern segment, - `last` flag, and `resolvedImportPolicy`. Return a candidate, a boolean meaning - selected versus ordinary skip, and a nullable `*Diagnostic`. Use the parent's - existing `site`, which is propagated from the selector's root candidate. - No candidate-set, accounting, or traversal-state mutation belongs here. -2. Move only the patterned branch's per-entry body into this helper. Preserve - its order: `path.Match`; match/hidden filtering; lexical/access path creation - and containment; `importEntryTarget` and existing diagnostic translation; - follow filtering; intermediate-directory eligibility; host/native physical - path selection and canonicalization fallback; candidate label/site creation. - Return existing safe codes, paths, and sites. Do not turn inspection errors - into skips or skip validation merely because exclusion will later match. -3. Replace that inline body with the helper call and candidate insertion. - Leave pattern validation, `explicitGlobCandidate`, directory enumeration, - per-segment union/sorting, final-file validation, exclusions, requiredness, - and source-admission timing in the selector. -4. Keep directory entry preparation separate. Reuse existing filesystem/link - primitives; do not introduce a generic entry strategy or unify differing - missing-target, literal-link, filtering, or recursion rules. Remove imports - only when genuinely unused after extraction. +### Semantic Observations And Shared Selection -Acceptance: the selector now expresses traversal without embedding preparation -details. Reuse `glob_selection_test.go`, `glob_test.go`, filesystem-link tests, -and the preceding sprint's directory-phase regressions. They must still cover -literal hidden/link components versus wildcard filtering, aliases and native -spelling, escaping/cyclic links, matched-directory errors before exclusion, -selection order, and bounded accounting. Add a behavioral case only for a gap -identified during extraction, not a unit test asserting the new helper exists. +Use a `historyObservation` record with: concrete affected `Path`; phase and +payload/operation IDs; reported operation `Path`; observation role; before/after +presence-side flags; sensitivity facts where observed; and an attribution +reference. Attribution resolves to an owned origin, reasons, and dependencies +in the model. Roles distinguish exact definition, ancestor replacement/removal, +control consumption, typed checkpoint, +and inventory-only evidence. The affected path need not equal the reported path. +Do not put rendered YAML or a copied subtree in each observation. -Focused check: -`go test ./internal/engine -run 'Glob|Directory|Link|Filesystem|Resource'`. +Source evidence needs both individual contribution references and composite +definition references. Represent a composite definition as a model-owned summary +over its ordered producer origins/contributions, not an independently assembled +`Metadata.history` bucket. Metadata selects the composite summary; explanation +selects the individual effects. Both use the same observation matcher and +attribution resolver. Checkpoints are explanation transitions and inventory +evidence, not new public metadata `ChangeDecoding` records. -## Stage 2 — Consolidate The Engine Defaults Representation +Implement `selectHistory(path)` inside the model. It returns ordered private +selections with matching shape/side, operation ID, reported path, and resolved +attribution. Both public projections and historical location fallback consume +these selections. Selection does not render YAML or replay the full configuration. -Finding: **F07**, engine representation. Owners: `internal/engine/import_spec.go`, -`load.go`, `layered.go`, `load_request.go`, `acquisition.go`, `options.go`, and -their callers/fixtures. Status: **complete**. Validation passed: -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Import|Glob|Directory|SourceVersion'` and `git diff --check`. Root facade callers remain pending Stage 3. +Selection rules: -1. Retain engine `ImportDefaults` with its existing five exported fields. - Remove private `importDefaults`, without a compatibility alias. Update - engine option/request/acquisition fields, helper signatures, readers, and - fixture literals to use the canonical type and exported default-field names. - Private containing fields such as `loadRequest.importDefaults` can keep their - names. Do not rename the distinct fields of `importDeclarationSpec` or - `resolvedImportPolicy` just because they have similar meanings. -2. Expose `ImportDefaults ImportDefaults` on engine `Options[T]` and - `LayeredOptions[T]`. Remove `OptionsWithImportDefaults`, - `LayeredOptionsWithImportDefaults`, and `privateImportDefaults`. Stage 3 changes - root callers; a temporary compile failure is preferable to an interim bridge. -3. Adapt `snapshotImportDefaults` to the canonical type, retaining nil boolean - pointers and nil versus non-nil empty pattern. Keep `cloneBool` and - `cloneStrings` where they still have real consumers. Keep current snapshot - call sites until Stage 3 establishes their final ownership placement. -4. Keep effective declaration policy resolution and validation semantics intact: - explicit false beats defaults, each control resolves independently, and - selector-specific applicability and depth checks stay unchanged. Do not - combine defaults with resolved policy or registration compilation. +1. Reject invalid paths and queries with no matching observed semantic shape. +2. Start with the pointer indexes and relevant prefix operations. Match the + complete concrete path using `matchesPathShape`; an ancestor key/index change + also changes every descendant's shape. Reuse existing path mechanics. +3. Exact definitions require the queried shape to exist in that definition. + An ancestor replacement is relevant only for a matching before or after shape; + it may remove one shape and introduce another at the same pointer. +4. Parsed tokens resolve against each observation's containers. A parsed query + can cover historical key and index states; emit a logical operation once when + both its sides match. Explicit `Key`/`Index` queries remain separate. +5. Derive `Previous` from preceding selected metadata definitions/operations, + not a discarded textual-pointer bucket. A newly introduced index must not + inherit the old mapping key's previous origin. A removed key still retains + its definition and the applicable ancestor-removal operation. +6. Retain existing projection-specific grouping, origin containment, and duplicate + suppression. Several strict contributions may supply one composite metadata + definition but several explanation events. Equal writes are not dropped merely + because their values compare equal. -Acceptance: one engine input-defaults type reaches every production path and -fixture; no equivalent private record or alias remains. Inspect ordinary, -layered, transitive-import, directory/glob, and test-helper call sites. The root -cutover and removal of redundant snapshots are explicitly pending until Stage 3. +Metadata query cost should be localized to indexed candidate observations and +returned records, without full-tree replay. Explanation may keep its existing +operation-local whole-tree replay; narrower replay is a separate deferred +experiment, not part of this sprint. -Run the import/default focused tests after Stage 3 if the root cutover prevents -building the package here; do not report that deferred check as passed. +During normalization, use one builder-local working document where needed +to determine concrete sides of effects whose producer payload is relative, such +as the child state immediately before an inherited parent is installed. Initialize +it from the baseline and advance it through existing value-replay helpers in +phase order; reset it to each typed checkpoint at the corresponding boundary. +Capture affected path/side facts before mutation, not a full tree per effect. +Register original resolution facts from their original before/after subtrees; +advance working state using only the net replay groups, not a fictitious sequence +of original callback assignments. Release the scratch document when preparation +ends. It is neither published evidence nor a new historical-path inventory: +membership still comes from registered producer/checkpoint observations. Reuse +producer-side facts instead of replay when they already establish the shapes. -## Stage 3 — Simplify Facade Defaults Construction And Snapshot Ownership +### Producer Evidence And Shape Preservation -Finding: **F07**, defaults handoff. Owners: root `conversion.go`, `lifecycle.go`, -`layered.go`; engine defaults/preflight/coordinator owners; `facade_import_defaults_test.go` -and `internal/engine/import_spec_test.go`. Status: **complete**. Validation passed: -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Import|Glob|Directory|SourceVersion'`, `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test . -run 'ImportDefaults|FacadeImport|SourceVersion'`, `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./...`, `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./...`, and `git diff --check`. +Normalize producer facts once into the model, not independently in each public +projection. Use existing concrete displaced paths, raw application roots, +sequence position descriptors, origin indexes, inheritance parent/effective +trees, and resolution before/after trees. -1. Set engine `ImportDefaults` fields directly in root `toEngineOptions` and - `toEngineLayeredOptions`. Retain `toEngineImportDefaults` as the explicit - root-to-engine type mapping, but map its booleans/pattern without copies. - Remove root `cloneImportDefaultBool` and `cloneImportDefaultStrings` after - confirming no other caller. Keep public root types and declaration contracts. -2. Keep `snapshotImportDefaults` in `loadSettings` as the load-entry ownership - operation for both APIs. Remove repeated snapshots in engine `LoadLayered` - request construction, `executeLoadRequest` acquisition-policy construction, - and `resolveImportPolicy`. Carry the owned defaults read-only thereafter. - Review all callers of those helpers, including test setup; direct declaration - resolution can read its input because it returns its own concrete policy. -3. Keep per-policy copies of the selected pattern, exclusions, and destination. - Do not borrow caller-owned storage beyond preflight, mutate the shared owned - defaults, or remove copying from unrelated option/record paths. Each new load - snapshots its own current inputs; add no reuse cache or ownership flag. -4. Replace the private conversion-snapshot fragment in - `TestImportDefaultsPreserveEmptyPatternAndRequiredness`, which converts options, - mutates inputs, and calls engine `Load`. It should no longer demand a snapshot - from a private conversion helper. Keep that test's public nil/empty, - requiredness, and inspection-evidence checks. -5. Protect the public snapshot contract with a compact ordinary/layered table: - use a main document with a version and imports, enable - `SourceVersionModeIfPresent`, and use a configuration type with version and - imported-value fields. In the main version-check callback, mutate the caller's - recursive default from true to false and its existing pattern element from - `*.cfg` to `*.skip`. This callback runs after preflight but before imported - discovery. Verify the original recursive/pattern selection still supplies a - value from a nested imported file. Use existing fixture helpers and no - concurrent mutation. A subsequent load with those changed defaults must omit - that imported contribution rather than reuse the prior snapshot. Keep fixtures - reusable or create fresh readers for each load. -6. Reuse or extend the small snapshot/policy tests for all four optional booleans, - explicit false, pattern mutation, nil, and non-nil empty pattern. Preserve - existing invalid-pattern-before-read/hook tests and declaration override, - transitive, underlay, and selected-overlay coverage. Do not assert exact copy - counts, pointer identities, or the private conversion boundary as public policy. +For replacement records, extend private `overlayRecord` with an +`introduced []historyPathOrigin` field, where `historyPathOrigin` contains a +concrete path and detached origin from the incoming contribution at its assigned +coordinates. Capture that evidence at the actual replacement/sequence-combination +producer before later changes can erase its shape. Preserve existing displaced +evidence. These are path/origin facts, not a retained full-tree snapshot per +replacement. Apply the same representation to CLI replacement preparation. -Acceptance: the engine/facade cutover builds; public defaults remain detached -before acquisition/callbacks, reused loads remain independent, and only genuine -ownership copies remain. Confirm the absence of full defaults snapshots at the -three removed downstream sites by source review, not production instrumentation. +Assign monotonically increasing operation IDs within phase order; keep a +substep ID for parent/child inheritance and similar multi-effect operations. +Index observations by those IDs and sort selected IDs, not map iteration order. +A removal observation and an introduction observation can refer to the same +operation/substep without becoming the same semantic affected path. -Focused checks: -`go test ./internal/engine -run 'Import|Glob|Directory|SourceVersion'` and -`go test . -run 'ImportDefaults|FacadeImport|SourceVersion'`. +The source adapter normalizes displaced definitions, replacement facts, and +surviving source definitions from the pre-inheritance structural root/origins. +It groups composite definitions using existing origin-containment rules, then +ties individual raw replay contributions to their observations. Do not reconstruct +historical shapes by parsing pointers from final origins. Sequence coordinates +come from `walkHistoryApplication` and the existing projection descriptors. -## Stage 4 — Construct Placement Directly Across The Facade +Observe every tree currently contributing historical membership, including the +baseline, structural input, both typed checkpoints, final projection, raw source +and CLI applications, inheritance parent/effective trees, and consumed controls. +Observe original resolution subtrees even when replay coalesces their records. +Record path/sensitivity facts from an inventory-only tree and release it when +no other consumer needs its values; do not revive an unused published structural +tree solely to enumerate paths. -Finding: **F07**, placement handoff. Owners: engine `destination.go`, `load.go`, -`layered.go`, normalized input and placement consumers; root `lifecycle.go`, -`layered.go`, and placement fixtures. Status: **complete**. Validation passed: -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'Destination|Placement|Item|SourceVersion'`, `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test . -run 'Placement|Destination|SourceInfo|SourceVersion|PublicFacadeBoundary|DependencyImportBoundary'`, `env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./...`, and `git diff --check`. +### Loading Handoffs And Frozen Ownership -1. Rename the existing engine enum and its constants to `PlacementMode`, - `PlacementModeMapping`, and `PlacementModeSequenceItem`, preserving underlying - `uint8` values and zero semantics. Use the same type throughout engine - placement parsing, normalization, acquisition, source evidence, and version - projection. Do not add a second raw-mode record or type alias. -2. Expose engine `Options[T].Destination` and `.PlacementMode`, and - `Input.PlacementMode`. Normalized `loadInput` and other private owner fields - can retain their names. Populate the normalized input from those fields. - Remove `OptionsWithPlacement` and `InputWithPlacement` and migrate all callers, - including the direct engine construction in root `records_test.go`. -3. In root `toEngineOptions` and `toEngineInput`, set destination using the existing - `toEnginePath` conversion and placement using - `engine.PlacementMode(options.PlacementMode)` or its input equivalent. - Preserve invalid enum values for `normalizeInput` to diagnose before reads. - Do not add validation/defaulting to the facade or a new setter/cast function. -4. Preserve normalization of literal/parsed destination keys, root-item rejection, - wrapper accounting, mounted/item source coordinates, and version projection. - Root `Path` is immutable and `toEnginePath` carries its private engine value; - keep normalization and actual mutable ownership copies. Do not redesign path - conversion or add redundant clones solely to replace the deleted decorator. -5. Leave source-result transport such as `SourceInfoPlacementModeForFacade`, - source-version conversion, sequence registration preparation, and opaque - records alone. They are not input setters targeted by this step. Adapt tests - mechanically to new engine construction without weakening public assertions. +Construct the builder's prefix in `preparePostDecodeOverrideContext`, after typed +CLI assignment but before application resolution. Supply baseline, structural +producer evidence, inheritance, pre-CLI checkpoint, CLI applications, and post-CLI +checkpoint in logical order. It must already support historical location fallback +for `referenceInput` at this point. -Acceptance: both public loading APIs retain zero/mapping and sequence-item -placement, errors before input consumption, final values, source metadata, and -history. Reuse the public placement tests plus destination/accounting, -item-import, mounted-version, and invalid-option cases. Root signatures still -contain no engine types, and engine exports remain below the internal boundary. +The callback's `resolutionInput` keeps only detached entry effective fields, +concrete entry paths, sources, and passive contexts, as today. It does not borrow +a growing history builder. Keep this view fixed while resolution mutates the +working Go configuration. -Focused checks: -`go test ./internal/engine -run 'Destination|Placement|Item|SourceVersion'` and -`go test . -run 'Placement|Destination|SourceInfo|SourceVersion|PublicFacadeBoundary|DependencyImportBoundary'`. +After successful resolution auditing, append original snapshots, derive replay +groups, register final shapes, and update effective metadata. Add resolution +evidence before rebuilding diagnostic locations for secret lookup/validation. +Prepare/freeze the model and admit its complete retained document graph at the +existing pre-secret boundary in `executeLoadRequest`. -## Stage 5 — Integrate, Document, And Verify The Result +`Inspection` owns final effective state plus one `*historyModel`. +`Metadata` holds effective fields/paths plus a private reference to that same +frozen model; remove its independent history/inheritance stores. Private frozen +state can be shared across these wrappers. Query outputs still clone paths, +origins, previous origins, reasons, and dependencies. Mutable builder state never +escapes and different loads do not share mutable evidence. -Findings: final acceptance for **C03, F07**. Status: **complete**. Validation -passed on Linux/amd64 (Go 1.26.10): -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off ./scripts/check.sh`, -`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./...`, and -`git diff --check`. Existing integration coverage was reviewed; no additional -case was needed. +Own one inheritance payload, not one for metadata and another for explanation. +Original resolution records remain authoritative; replay groups contain record +IDs, merged presentation annotations, and references to existing before/after +roots. They do not replace or discard original records. Reuse already owned +immutable trees; clone once only where producers could otherwise mutate them. +Keep each required clone charged to the existing retained-node counter. -1. Review both paths together: defaults resolving wildcard discovery in ordinary, - layered, and transitive imports; placement carrying the resulting sources - through composition and inspection; and failures stopping before later hooks. - Existing integration tests own these interactions. Add only a concrete missing - case rather than a second copy of the complete matrix or a new fixture framework. -2. Inspect the resulting handoffs. Confirm the glob selector no longer embeds - per-entry preparation, the engine has one defaults input type, direct fields - replaced the four input decorators, and the load snapshot is not repeated at - each private representation. Keep domain-specific policy/registration and - root conversion boundaries, necessary ownership copies, and existing budgets. -3. Update `docs/internal/imports.md` for the selector/preparation split and - `docs/internal/overview.md` for defaults conversion, preflight snapshot ownership, - and direct placement construction. Keep algorithms private and avoid public - performance or copy-count guarantees. No ADR/policy change is needed. -4. Replace C03/F07 detail in the first two `docs/roadmap/future.md` entries with - short pointers to `internal-boundaries.md`. Retain their heading anchors for - existing audit links; leave other future candidates unchanged. Correct old - roadmap references that would otherwise mistake this replacement plan for - the previous sprint's completed record: use - `bb5540b:docs/roadmap/implementation.md` for that historical plan. Do not reopen - the prior audit or retire unrelated planning records in this sprint. -5. Format changed Go files, finish deferred checks, run the final checks below, - and inspect the complete diff for API, dependency, semantics, or scope changes. - Record actual results and platform limitations here. Commit focused nonempty - units and hand off a clean workspace; do not create empty validation commits. +### Internal Readers And Retained Accounting -Final validation, following the existing development guide: +Provide model methods for metadata selections, historical path enumeration, +latest historical document location, sensitivity candidates/dependency edges, +and retained document-root enumeration. These are private methods, not public +extensions. Source records and source-version evidence retain their existing +owners; include the latter's mounted sensitivity candidates as today. -```sh -env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off ./scripts/check.sh -env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./... -git diff --check -``` +Secret classification consumes all relevant evidence, including original +resolution dependencies and inherited/control links, not only public projected +events. Preserve existing parsed/concrete predicate candidates and union +classification by pointer. An attribution correction must not expose a value +previously protected because another historical shape shared that pointer. -The everyday check includes consumers, documentation links, and public/dependency -boundary tests. Confirm those existing tests ran rather than adding redundant -final invocations. Report filesystem/platform skips accurately; express macOS -validation, CI completion, release publication, extended fuzz campaigns, and -benchmarks are not additional acceptance requirements. +Retained-root enumeration includes every document node reachable from the model, +its payloads and checkpoints, and the final inspection projection. Derived +indexes hold IDs or references to those same roots. Reuse `retainedNodeCounter` +for pointer-identity deduplication; distinct copies still count. Keep query-local +replay copies outside the published-retention count, as today. This is not a +general heap or allocation limit. -No product or architectural question remains open. The concrete choices above -complete the plan without changing the roadmap's public contracts; private -formatting and file organization can follow local idiom. +### Diagnostic Ordering Rule + +Preserve related-location order for `CodeComposeConflict` and retain generic +related-location sorting for other codes. This code already crosses the public +facade unchanged; no private marker or message matching is needed. Its ordinary +claimant producer has a semantically ordered list, and duplicate-identity +producers currently have one related claimant, whose result is unchanged. +Keep canonical ordering of diagnostic records and all primary-location choices. +Apply this rule at the shared canonicalization function, including rendering of +public records converted back into engine records. + +## Producer And Consumer Migration Map + +| Existing owner | Final owner/action | +| --- | --- | +| `metadataFromDecoded`, `collectFieldInfo` | Keep effective-field construction; baseline/source history goes to model normalization. | +| `applyOverlayMetadata`, `appendInputOriginEvent`, `appendInputChangeEvent` | Replace history-bucket reconstruction with source/CLI semantic observations and composite summaries inside the model. Retain useful origin-containment helpers. | +| `applyInheritanceMetadata`, `historyWithInheritance` | Remove independent source-view/history insertion; inheritance observations and common selection supply both projections. | +| `projectedInheritanceChanges`, `appendInheritanceExplanation` | Share the transfer/control attribution resolver in the model; replay helpers only apply values. | +| `appendPostDecodeCLIHistory`, `overrideMetadataRecords` | Replace history assembly; retain/adapt useful displacement preparation as CLI evidence production. | +| `applyResolutionMetadata`, `appendResolutionDescendantHistory` | Retain effective-field/origin updates; original model records and shared selection own history and previous attribution. | +| `finalizeMetadataPaths`, inheritance-history index | Keep effective indexing; model observations own historical shapes, membership, enumeration, and operation indexes. | +| `Inspection.Explain` phase/relevance/origin orchestration | Consume model selections and owned replay groups, preserving safe value replay/rendering. | +| `metadataFieldLocation` | Consume model latest-location selection, using the concrete query path. | +| `classifySecretPathsWithEvidence` historical reads | Consume model candidates, original dependency edges, and inheritance links; retain fixed-point sensitivity closure. | +| `prepareInspectionHistory`, `publishLoadResult`, `addInspectionHistory` | Prepare and freeze one owner; enumerate/count the new retained ownership graph before secrets/validation. | +| `cloneMetadata`, `Inspection.Metadata` | Clone effective mutable records as needed and share only frozen private history; query outputs remain detached. | + +## Validation Conventions + +Use the installed compatible Go toolchain and existing dependencies. From the +repository root, use `GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off` for Go checks. +Keep disposable artifacts outside the checkout. Do not change dependencies for +tooling or run publication commands. + +Each stage names focused behavior owners. Run its focused tests when buildable; +otherwise record them as pending. New regression names must be included in the +selected expression or run explicitly. Reuse existing cases instead of duplicating +full matrices. Do not rewrite correct expectations to accommodate a refactor; +change only defect expectations and tests tied to retired representations. + +## Stage 1 — Correct Callback Presence And Defaulting + +Finding 1. Owners: `resolution.go`, `load_metadata.go`, resolution/provenance tests, +and one root regression in `facade_compatibility_test.go` or a focused new facade +test file. Status: pending. + +1. Add a private entry-presence helper using `resolutionInput.lookup` and its + `FieldInfo.Explicit`. Use it in `Resolution.IsExplicit` after existing + schema-path validation and in `Default` after existing helper-target checks. + Remove the now-unused raw presence field from `resolutionState` if no other + production consumer remains. Do not change `InputInfo` error semantics. +2. Exercise explicit numeric keys and indexes beneath `any` in both directions. + Check parsed pointers, entry lookup/presence agreement, and an absent path. +3. To exercise `Default`, change the working dynamic container to the other shape, + record its parent normalization, default the new child through a correctly + typed local target, and write it back. The old shape remains explicit in the + entry view; the new shape must not suppress defaulting. Preserve final helper + matching and ordinary explicit zero/false/null cases. + +Acceptance: the audit's first reproduction is corrected without changing +schema-invalid-path diagnostics, closed-context panics, or helper assignment rules. +Focused check: `go test ./internal/engine -run 'Resolution|Provenance|Default'` +and the selected root regression. + +## Stage 2 — Correct Final Explicitness Across Shape Changes + +Finding 2. Owners: `applyResolutionMetadata`, `refreshResolutionFields`, +`resolveLoadInput`, and resolution/metadata tests. Status: pending. + +1. Pass the frozen `resolutionInput` to effective metadata refresh rather than + attempting to infer entry shape from a final pointer bucket. +2. Walk the final projection with concrete paths. Obtain explicitness from the + matching entry field; a missing or shape-mismatched entry contributes false. + Retain the applicable resolution origin and final null state. Preserve the + existing delta-coverage origin rules and remove genuinely absent final fields. +3. Cover key-to-index and index-to-key changes, a change at an ancestor of a + deeper queried field, and same-shape ancestor normalization. Verify entry + queries stay fixed and final `Lookup`/`IsExplicit` agree. Add no sequence + record-identity inference or transient-mutation tracking. + +Acceptance: the new semantic path is non-explicit while surviving same-shape +input remains explicit. Focused check: +`go test ./internal/engine -run 'Resolution|Metadata|Provenance'`. + +## Stage 3 — Introduce The Shared Evidence And Selection Core + +Finding 3 architecture. Owners: new `history_model.go` and `history_select.go`, +existing path/lookup helpers, focused history-selection tests. Status: pending. + +1. Implement the selected model, builder, phase/role enums, payload ID references, + and semantic observation types. Keep phase producers in later stages; do not + populate a second legacy history store from this core. +2. Implement concrete-shape inventory insertion with deduplication using actual + segment kinds, and observation indexing by pointer and relevant prefix. + Keep first-observed data order separately from sorted enumeration. +3. Implement shared selection, before/after-side matching, logical operation + deduplication for parsed queries, and attribution-reference resolution. + `Previous` is computed from the selected metadata sequence, not inherited + from a pointer-only record. Keep selectors independent of YAML serialization. + Add builder scratch-state support for the normalization procedure above; + do not retain per-event full-tree copies or query-time mutable caches. +4. Test a numeric key/index collision, an ancestor shape collision affecting a + deeper path, introduced/removed sides of one operation, parsed traversal, + and a never-observed descendant. Use small actual document fixtures. + +Acceptance: both public projections have one internal semantic-selection protocol +to consume. Focused check once buildable: +`go test ./internal/engine -run 'History.*Select|History.*Shape|Path'`. + +## Stage 4 — Normalize Baseline And Ordinary Source Evidence + +Owners: new `history_source.go`, `load_metadata.go`, `overlay.go`, composition +evidence consumers. Status: pending. + +1. Register baseline definitions by walking the canonical baseline with concrete + paths and default origins. Keep absent roots and explicit null distinct. +2. Build the source phase from structural applications, raw root/origins, + displacement records, and concrete introduced-path facts. Add introduced + evidence to `mergeOverlayMappings` and `recordOverlayReplacement` while the + relevant shape exists. Extend `cloneOverlayRecords` to detach the new path/ + origin facts. Do not retain a new full root per replacement. With `NoSource`, + keep the source phase empty rather than fabricating an empty source mapping. +3. Move source-definition grouping/origin-containment behavior out of metadata + history building into this normalization. Preserve displaced and surviving + definitions, composite mapping locations in assembly order, empty mappings, + and equal definitions. Keep raw source application values for explanation. +4. Link fine contribution and composite summary observations to model-owned + attribution. Public projections must not separately recover locations by + traversing raw applications or by parsing final pointer strings. + +Acceptance: baseline and ordinary source/overlay semantic observations preserve +the existing metadata-versus-explanation distinction. Reuse compose, overlay, +provenance, and explanation cases; focused check: +`go test ./internal/engine -run 'Compose|Overlay|Provenance|Explain'`. + +## Stage 5 — Normalize Projected Collection Evidence + +Owners: `sequence_history_projection.go`, sequence combination evidence, +`history_source.go`, and `history_sequence_test.go`. Status: pending. + +1. Extend source normalization to assigned sequence coordinates using + `walkHistoryApplication`, `historyApplicationLocalPath`, and existing sequence + contribution indexes. Preserve append offsets, mapped upsert outputs, + replacement positions, and item-local/nested source placement. +2. Capture concrete introduced-path facts in `applyOverlaySequenceEvidence` + alongside existing displaced facts, for whole-sequence and matched-record + replacements. Distinguish the operation's container or + record path from the affected descendant's actual shape. +3. Preserve whole-record replacement/removal events when a higher record omits + an old descendant, and prevent a contribution that never addressed a record + from acquiring its attribution. Do not alter collection selection or merge + algorithms, source ordering, or identity equality. + +Acceptance: raw and composite collection observations have common assigned paths +and correct displacement attribution. Focused check: +`go test ./internal/engine -run 'SequenceHistory|Mapped.*History|Tier.*History|ProjectedSequenceHistory|Destination'`. + +## Stage 6 — Normalize Inheritance And Control Evidence + +Owners: new `history_inheritance.go`, `inheritance_history.go`, +`inheritance_explain.go`, inheritance operation producers. Status: pending. + +1. Register one ordered inheritance payload. Produce observations for control + removal/cancellation, parent transfer, effective child contribution, and + displaced paths using parent/effective trees and their origin indexes. Use + builder scratch state where the actual pre-transfer child/enclosing shape is + needed; neither the parent nor effective child alone proves that old shape. +2. Move transfer/control attribution and dependency selection into the common + resolver. Adapt useful parts of `transferredOperationOrigin` and + `projectedInheritanceChanges`; do not leave one attribution implementation for + metadata and another for explanation. +3. Preserve destination-local paths, contributor traces, directive locations, + equal child writes, nested unresolved templates, and child identity fields. + Apply concrete before/after shape matching at every ancestor. +4. Keep value replay helpers that install the parent, restore child identity, + and install the effective child, but have them receive selected attribution + rather than compute it independently. + +Acceptance: controls and transfers are shared evidence, including paths omitted +by a particular public projection. Focused check: +`go test ./internal/engine -run 'Inheritance.*History|History.*Inheritance|RecordInheritance|NestedInheritance'`. + +## Stage 7 — Normalize Typed Checkpoints And CLI Evidence + +Owners: new `history_cli.go`, `override_context.go`, override metadata/replay +helpers. Status: pending. + +1. Register pre-CLI and post-CLI canonical checkpoints with their origin indexes + on the correct sides of the CLI contribution phase. Preserve raw-versus-typed + number/string representations and retained defaults. +2. Normalize prepared CLI applications and displacement/introduced facts into + the same source-effect representation, with CLI attribution. Adapt + `overrideMetadataRecords`/`collectAffectedOverrideOrigins` as producers, not + a second public-history assembly path. +3. Register checkpoint observations for inventory and conditional reconciliation. + Only explanation emits decoding transitions when replay differs; metadata + continues to expose definitions and operations rather than these transitions. +4. Cover the audit's CLI mapping-to-sequence shape change and its reverse, + equal writes, whole-sequence removal, partial mappings, and default + reconciliation. Reuse existing post-inheritance CLI chronology tests. + +Acceptance: the model distinguishes baseline, structural source state, typed +pre-CLI input, raw CLI application, and typed post-CLI entry state. Focused check: +`go test ./internal/engine -run 'CLI.*History|Explain|Decoding|IntegerVersionInspection|Override'`. + +## Stage 8 — Normalize Original Resolution And Net Replay Groups + +Owners: new `history_resolution.go`, `history.go`, original resolution snapshots +and coverage indexes. Status: pending. + +1. Store the ordered original snapshots after successful audit. Normalize their + before/after subtrees into concrete observations and retain every original + reason/dependency, even if explanation coalesces its public event. +2. Adapt `coalescedResolutionSnapshots` to return groups of original record IDs, + a covering record/root reference, and merged presentation annotations. Preserve + ordering, first-occurrence reason/dependency deduplication, normalization + dominance, and the existing overlapping-record coverage rules. +3. Keep metadata's specific original record attribution and explanation's net + subtree replay as explicit projections of those references. Compute shape- + specific previous origins through common selection, not copied `Previous` + from an earlier pointer bucket. +4. Preserve original subtree inventory and sensitivity dependencies even where + a covering replay group omits a separate public record. + +Acceptance: shape-changing resolution history is selectable and original +attribution is not lost to replay grouping. Focused check: +`go test ./internal/engine -run 'Resolution|Coalesced|Overlapping|Explain'`. + +## Stage 9 — Complete Historical Inventory And Internal Query Services + +Owners: model finalization, `metadata.go`, history selection indexes. +Status: pending. + +1. Derive historical membership and enumeration from all model observations and + registered payload roots, including inventory-only checkpoints and controls. + Do not maintain the old parallel tree-walk inventory in `finalizeMetadataPaths`. +2. Preserve all concrete shapes for one pointer, but return one sorted parsed + `Path` per pointer from `HistoricalPaths`. Root/default-only paths and removed + descendants remain included; never-observed descendants remain absent. +3. Provide a latest historical location query over selected definitions and + previous origins, a complete dependency/candidate iterator, and an eager + immutable lookup over model document roots. Preserve producer chronology; + indexes are accelerators, not alternate evidence owners. +4. Retain `effectivePathIndex` for entry/final shape lookup. Register concrete + sensitivity facts while observing any tree whose values can then be released. + +Acceptance: membership and all internal historical queries have one evidence +source. Focused check: +`go test ./internal/engine -run 'HistoricalPaths|Metadata|History.*Shape|SecretClassification'`. + +## Stage 10 — Cut Metadata History Over To The Model + +Owners: `Metadata`, `Metadata.History`, `cloneMetadata`, model metadata projection. +Status: pending. + +1. Replace metadata's independent history map, inheritance slice, and inheritance + index with a private frozen-model reference. Keep effective fields/paths and + their shape-aware lookup separate from historical evidence. +2. Implement `History` as shared selection followed by metadata projection: + default definitions, composite source summaries, inheritance operations, + CLI operations, and original resolution attribution. Derive previous origins + after shape filtering and projection-specific grouping. +3. Clone every returned nested record. Share only private frozen model state + when copying `Metadata`; preserve zero-value behavior. +4. Add a focused public regression comparing explicit key/index histories after + CLI and resolution shape changes. Check no false base definition or previous + origin appears for the introduced shape, while removed paths retain applicable + ancestor replacement history. Include a parsed-query/enumeration case. + +Acceptance: finding 3's metadata defect is fixed without calling `Explain`, +rendering YAML, or replaying full trees per metadata query. Focused check: +`go test ./internal/engine -run 'Metadata|Provenance|History'` and the selected +root history regressions. + +## Stage 11 — Cut Explanation Over To Common Selections + +Owners: `explain.go`, `inheritance_explain.go`, `snapshot.go`, model replay helpers. +Status: pending. + +1. Drive phase chronology and event relevance through model selections. Remove + independent relevance/origin interpretation from `Inspection.Explain` and + inheritance explanation orchestration. Keep safe snapshot serialization and + ordinary value-application helpers. +2. Replay source, inheritance, checkpoint, CLI, and grouped resolution payloads + through references from the model. Use each selection's resolved attribution; + do not call metadata's public `History` or translate its records into values. +3. Preserve baseline presence, conditional decoding reconciliation on both sides + of CLI, raw superseded values, equal input/child/CLI operations, resolution + group reasons/dependencies, secret-reference annotations, and unknown-path + behavior. Keep caller mutation and repeated queries detached. +4. Compare both interfaces on semantic attribution while asserting their selected + differences for composite mappings, decoding, and overlapping records. + +Acceptance: both views use common semantic selection and attribution, not merely +the same payload storage with old independent interpretation. Focused check: +`go test ./internal/engine -run 'Explain|Explanation|History|Render|Diff'`. + +## Stage 12 — Integrate Load Prefixes And Diagnostic Location Readers + +Owners: `preparePostDecodeOverrideContext`, `resolveLoadInput`, +`documentWithMetadataLocations`, `metadataFieldLocation`, and load handoffs. +Status: pending. + +1. Thread one builder through `postDecodeOverrideContext` and `resolvedLoad` using + the lifecycle specified above. Create the pre-resolution prefix once; append + resolution evidence once. Remove transport fields that duplicate model-owned + applications, checkpoints, origins, and snapshots after their callers migrate. +2. Keep the callback's `resolutionInput` as its independent fixed effective view. + Do not put a mutable history reference in that context or let publication + change its captured fields/sources. +3. Change historical location fallback to take a concrete `Path` and query the + current model prefix. Preserve the existing priority: effective source + location first, then latest applicable historical location, then the nearest + structural input fallback. Shape filtering must not fabricate an exact + location from a different key/index state. +4. Ensure prefix queries work before resolution and after resolution, before + secrets and validation need their `referenceInput`. Do not postpone model + construction until `publishLoadResult`. + +Acceptance: diagnostic attribution has no dependency on the retired history map. +Reuse metadata-location, secret-location, CLI, and provenance tests. Focused check: +`go test ./internal/engine -run 'Location|Provenance|ResolutionInput|CLISecret|Validation'`. + +## Stage 13 — Migrate Historical Sensitivity Readers + +Owners: `secret.go`, `secret_propagation.go`, model candidates/dependencies. +Status: pending. + +1. Replace reads of metadata history and private inheritance copies with the + complete model candidate and dependency services. Preserve original resolution + dependencies, inherited contributor/control links, historical tags, and + source-version mounted evidence. +2. Preserve parsed and concrete candidate shapes used by current predicate/tag + classification. Fold sensitivity by pointer conservatively after collecting + relevant shapes; neither history projection's omissions may erase candidates. +3. Keep fixed-point dependency closure and cross-result diff masking unchanged. + Do not narrow classification because an exact metadata query now excludes a + different historical shape at the same pointer. + +Acceptance: effective output, historical snapshots, version evidence, and paired +diff snapshots retain disclosure behavior. Focused check: +`go test ./internal/engine -run 'Secret|Sensitive|Redact|Diff'` and existing root +secret/diff integration tests. + +## Stage 14 — Publish One Frozen History Owner + +Owners: `Inspection`, `prepareInspectionHistory`, `publishLoadResult`, +`Inspection.Metadata`, cloning and lookup setup. Status: pending. + +1. Finish the model before publication, with eager indexes and final observations. + Attach the same frozen owner to inspection and metadata. Remove independent + inspection copies of source/CLI applications, checkpoint origins, original + and grouped resolution payloads, and inheritance evidence once moved. +2. Retain only document roots needed for active replay, effective rendering/diff, + and classification. Convert inventory-only projections to path/sensitivity + facts rather than publishing an otherwise unused structural tree. +3. Detach producer-owned mutable slices, origins, and trees where necessary once + at the handoff; reuse already immutable engine-owned roots. Preserve final + configuration detachment, validated secret state, and no further lookup or + callback invocation during publication. +4. Reuse existing detached-query, independent-load, and concurrent read-only + inspection tests. Update representation-only fixtures expecting two private + inheritance copies; replace that assertion with protection against mutation + leaking through either public projection. + +Acceptance: one frozen history model owns the published evidence and no query +mutates it. Focused check: +`go test ./internal/engine -run 'Detached|Independent|ConcurrentReadOnly|History|Explain'`. + +## Stage 15 — Reconcile Complete Retained-History Accounting + +Owners: `executeLoadRequest`, `retainedNodeCounter`, model root enumeration, +`history_budget_test.go`, inheritance budget tests. Status: pending. + +1. Replace `addInspectionHistory`'s old field/copy enumeration with the actual + model and final-inspection root graph. Include all checkpoint, application, + inheritance, original resolution, and any distinct replay-retained roots. + Count shared nodes once by pointer; check required clones before allocating + them where practical. +2. Perform final admission at the existing pre-secret/pre-validation boundary. + After that boundary publication must not introduce an uncounted retained tree; + keep index finalization there if it retains additional roots. Leave the + existing structural-expansion limit checks intact. +3. Update the independent test graph enumeration for the new owner. Derive an + exact small fixture requirement, test success at that count and rejection + below it, and assert no secret lookup or validator call occurs on rejection. +4. Cover ordinary loading and a layered fixture combining inheritance, CLI, + original/overlapping resolution, and checkpoints. Drop obsolete copy-count + assertions, not ownership, complete-accounting, or failure-timing protection. + +Acceptance: the existing quota governs the complete new retained graph; no new +quota or representation-specific node total is promised. Focused check: +`go test ./internal/engine -run 'History.*Budget|HistoryNode|Retained|ProjectionBudget'`. + +## Stage 16 — Remove Superseded Attribution And Repair Test Seams + +Owners: all entries in the migration map and tests constructing private inspection +or metadata values. Status: pending. + +1. Trace remaining production reads/writes of old history/inheritance fields and + helpers. Remove history-building portions of `metadataFromDecoded`, + `applyOverlayMetadata`, `appendPostDecodeCLIHistory`, + `appendResolutionDescendantHistory`, and `historyWithInheritance` once their + replacements are active. Preserve effective-field construction and reusable + domain mechanisms with real consumers. +2. Remove the old parallel historical path walker, duplicate published payload + ownership, and independent explanation relevance/attribution paths. Do not + leave them for sensitivity, location fallback, or tests alone. +3. Update private test constructors to build shared evidence through actual + adapters. Retain behavioral assertions. Rewrite or remove isolated tests of + a deleted representation only when their meaningful protection is preserved + at a surviving owner; do not add production compatibility shims for fixtures. +4. Check each migration-map row against actual references. All historical + membership and attribution readers must now trace to the model. A shared + container wrapping both old reconstruction paths is not completion. + +Acceptance: there is one active historical attribution system. Run the full +ordinary suite when buildable: `go test ./...`. + +## Stage 17 — Preserve Composition Conflict Ordering End To End + +Finding 4. Owners: `canonicalDiagnostics`, composition diagnostic producers, +root diagnostic conversion/rendering tests. Status: pending. + +1. Implement the code-based ordering rule specified above. Verify every + `CodeComposeConflict` producer; keep claimant order and leave single-related + duplicate-identity diagnostics unchanged. Retain generic sorting otherwise. +2. Add the audit fixture using `fstest.MapFS`: main imports a/b/c; a imports z; + b/c/z each claim x. Assert primary b and related c,z despite acquisition IDs + 4,5,3, without assuming source IDs are assembly keys. +3. Assert the same order from public `LoadError.Diagnostics` and after passing + those records to root `WriteDiagnostics`. Preserve detached records, safe + formatting, short writes, canonical ordering of diagnostic records, and + generic related-location sorting for a non-composition code. + +Acceptance: accumulation and facade round-tripping no longer reorder composition +claimants. Focused check: +`go test ./internal/engine -run 'Diagnostic|Compose|Conflict'` and the selected +root diagnostic regression. + +## Stage 18 — Integrated Verification And Documentation + +Owners: integrated engine/facade, documentation, audit and plan status. +Status: pending. + +1. Run all deferred focused checks. Review representative ordinary and layered + public loads for agreement among final configuration, entry/final presence, + origins, history, explanation, source contexts, and safe effective output. + Use existing examples/integration fixtures; do not invent another matrix. +2. Ensure regressions include a deeper ancestor shape change, inventory omitted + by public grouping, equal contributions, raw superseded values, decoding on + both sides of CLI, inherited controls/identity, mapped sequence displacement, + and overlapping resolution intent. Extend an existing owner only for a + remaining meaningful gap. Verify intentional projection differences as well + as shared semantic attribution. +3. Run with the same installed toolchain: + + ```sh + env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off ./scripts/check.sh + env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./... + ``` + + The race run protects the changed frozen-ownership handoff using existing + concurrency coverage; it does not add a new public concurrency promise or + release gate. No benchmark campaign or external consumer update is required. +4. Update `docs/internal/overview.md` for the implemented shared-history owner, + concrete responsibilities, and lifecycle handoffs. Update Go comments and + `docs/config.md` only where needed to clarify corrected existing behavior or + remove obsolete mechanics. Preserve canonical ownership and accepted ADRs; + describe no new public guarantee. Adjust contributor test links only if their + owners move. Do not retire these roadmap records during implementation. +5. Mark the four audit findings completed with concise implementation/test + evidence; mark this plan and the feature roadmap implemented only after the + full integrated result satisfies acceptance. Review the final diff for scope + and unrelated work, record actual validation, and commit completed units. + +Completion: all four reproductions are corrected; both projections and internal +historical readers derive attribution and membership from one model; old parallel +machinery is removed; ownership and quota timing hold; applicable checks pass. +The result must compile and be coherent even though intermediate stages need not. + +## Open Questions + +None. Roadmap-level decisions are settled, and this plan selects the private +evidence representation, semantic-selection protocol, lifecycle handoffs, +diagnostic rule, migration responsibilities, and validation boundaries. If an +unforeseen issue requires changing public semantics or the selected ownership +architecture, report that concrete conflict rather than silently narrowing the +target or adding a new restriction. diff --git a/docs/roadmap/interface-remediation.md b/docs/roadmap/interface-remediation.md index 86cd1ee..815c543 100644 --- a/docs/roadmap/interface-remediation.md +++ b/docs/roadmap/interface-remediation.md @@ -6,9 +6,9 @@ Planning baseline: `1f64673` (v0.10.2 implementation plus documentation changes) This roadmap covers the four findings in the [interface audit](interfaces.md). The audit owns reproductions, evidence, and finding numbers. This document owns -the combined target, required changes, and general dependency order. A subsequent -implementation plan should own concrete stages, private implementation choices, -validation commands, and progress. +the combined target, required changes, and design intent. The +[implementation plan](implementation.md) owns concrete stages, private +implementation choices, validation commands, and progress. ## Purpose And Scope @@ -264,41 +264,6 @@ would therefore be insufficient. No public ordering option is needed for this correction. Keep primary selection, conflict detection, acquisition order, and dependency-ready scheduling unchanged. -## General Implementation Order - -1. Prepare the concrete shared-evidence design and focused regression cases. - Map existing producers and consumers to the new owner, distinguish common - attribution from presentation rules, and identify the old paths to remove. - Select representations and indexes that preserve existing query and lifetime - needs without adding public contracts. -2. Repair entry-state presence queries and `Default` (finding 1). This is a local - correction that can proceed independently of the larger history work. -3. Repair final explicitness preservation (finding 2), retaining the shape evidence - needed by metadata updates. Coordinate this work with history construction so - the two fixes do not introduce competing definitions of path identity. -4. Build the shared model and migrate metadata history, explanation, sensitivity - dependencies, and diagnostic-location readers. Preserve phase evidence and - derive both public projections through common semantic attribution. Remove - the superseded reconstruction paths and reconcile retained-history accounting. - Verify finding 3 and its interaction with final presence metadata; repairing - pointer buckets alone does not complete the selected architecture. -5. Complete composition diagnostic ordering (finding 4) as an independent change; - it may proceed alongside the path work. Check rendering as well as the - structured error before considering it complete. -6. Review the integrated result, run applicable development checks, and update - affected implementation documentation and finding status. - -This work will be completed in one implementation sprint. Intermediate stages -and commits need not be coherent or compile, and will not be made available to -consumers. The order above describes dependencies within that sprint. It does -not require temporary adapters or parallel implementations merely to keep each -stage buildable. - -Keep changes focused and the four findings individually traceable. Run focused -checks when the affected surface is buildable, and complete any pending checks -against the integrated result. The final sprint result must compile, pass the -applicable development checks, and satisfy the full completion criteria below. - ## Validation And Completion Follow the [testing policy](../policy/testing.md) and use the