Complete interface contract remediation

This commit is contained in:
2026-10-26 18:23:58 +00:00
parent 1954052631
commit 98c8b7c842
6 changed files with 64 additions and 18 deletions

View File

@@ -151,6 +151,27 @@ descriptor caching and type policy, and
inline field assembly. [`decode.go`](../../internal/engine/decode.go) consumes inline field assembly. [`decode.go`](../../internal/engine/decode.go) consumes
those descriptors for typed decoding. those descriptors for typed decoding.
History and inspection use one private evidence owner. The
[`history_model.go`](../../internal/engine/history_model.go) builder receives
baseline, source-composition, inheritance, typed-checkpoint, and CLI evidence
in [`preparePostDecodeOverrideContext`](../../internal/engine/override_context.go),
before application resolution begins. The callback retains its separate fixed
entry view; it does not read a builder that continues to change. After successful
resolution auditing, [`resolveLoadInput`](../../internal/engine/load_result.go)
adds the original resolution records and their net replay groups. At the existing
pre-secret admission boundary, [`prepareInspectionHistory`](../../internal/engine/load_result.go)
freezes that builder and counts the retained document roots before secret lookup
and validation.
The frozen model is shared by `Metadata` and `Inspection`. Its shape-aware
selection in [`history_select.go`](../../internal/engine/history_select.go)
drives metadata history, explanation, and historical-path membership; the model
also supplies historical diagnostic locations and sensitivity/dependency
evidence. `Inspection` replays selected payloads to produce detached, safely
rendered values, while metadata queries return detached attribution records.
History and explanation behavior is covered by focused `history_*_test.go`
tests alongside metadata, secret, inheritance, and facade integration tests.
Behavioral ownership follows the same handoffs: imports and grouped lifetimes are Behavioral ownership follows the same handoffs: imports and grouped lifetimes are
covered by `imports_test.go`, `load_request_test.go`, and focused source, covered by `imports_test.go`, `load_request_test.go`, and focused source,
discovery, and destination tests; inheritance by the inheritance test files; discovery, and destination tests; inheritance by the inheritance test files;

View File

@@ -1,6 +1,6 @@
# Interface Contract Remediation Implementation Plan # Interface Contract Remediation Implementation Plan
Status: in progress. Stages 1–17 are complete; Stage 18 remains pending. Status: implemented. Stages 1–18 are complete.
Baseline: `f6d54a094a2b5ada5748686620659399dce7ebf0`. Baseline: `f6d54a094a2b5ada5748686620659399dce7ebf0`.
Audience: a Luna coding agent executing the stages sequentially. Audience: a Luna coding agent executing the stages sequentially.
@@ -743,7 +743,13 @@ root diagnostic regression.
## Stage 18 — Integrated Verification And Documentation ## Stage 18 — Integrated Verification And Documentation
Owners: integrated engine/facade, documentation, audit and plan status. Owners: integrated engine/facade, documentation, audit and plan status.
Status: pending. Status: complete. Validation:
`GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine -run 'TestHistorySelectionMatchesDeepSidesOfAncestorShapeChange|TestMetadataFinalizationRegistersResolutionInventoryAndRoots|TestOverrideEqualReplacementStillAppearsInHistory|TestCLIHistoryEvidenceKeepsCheckpointsAndConditionalReconciliation|TestInheritanceHistoryPreservesCancellationAndSupersededDirective|TestRecordInheritanceHistoryPreservesChildIdentity|TestMappedSequenceHistoryReplacesWholeRecordsAndKeepsDisplacedEvidence|TestExplanationReplaysResolutionAdditionsAndOverlappingIntent|TestHistoryResolutionRetainsOriginalShapeAttributionBehindReplayGroup|TestExplainReplaysCLIResolutionContainersAndSafeHistoricalValues' -count=1`,
`GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test . -run 'TestFacadeResolutionPresenceUsesDynamicEntryShape|TestPublicHistoryUsesResolutionShapeAttribution|TestPublicHistoricalPathsEnumerateContextualShapes|TestFacadeCompositionConflictKeepsClaimantOrder' -count=1`,
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off ./scripts/check.sh`,
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test -race ./...`,
and `git diff --check` passed. The check script required gofmt alignment in
`internal/engine/resolution_index_test.go`, which was applied mechanically.
1. Run all deferred focused checks. Review representative ordinary and layered 1. Run all deferred focused checks. Review representative ordinary and layered
public loads for agreement among final configuration, entry/final presence, public loads for agreement among final configuration, entry/final presence,

View File

@@ -1,7 +1,7 @@
# Interface Contract Remediation Roadmap # Interface Contract Remediation Roadmap
Status: target settled, including shared history ownership; implementation has Status: implemented. The shared history owner and all four audit corrections
not begun. are complete; validation is recorded in [implementation.md](implementation.md).
Planning baseline: `1f64673` (v0.10.2 implementation plus documentation changes). Planning baseline: `1f64673` (v0.10.2 implementation plus documentation changes).
This roadmap covers the four findings in the [interface audit](interfaces.md). This roadmap covers the four findings in the [interface audit](interfaces.md).
@@ -330,6 +330,5 @@ The selected common underlying model addresses both concerns. This accepts a
larger internal refactor than a local shape-filtering fix. larger internal refactor than a local shape-filtering fix.
No significant open decision remains at roadmap level. Private representation, No significant open decision remains at roadmap level. Private representation,
indexing, and helper choices belong in the implementation plan. This roadmap indexing, and helper choices are recorded in the completed implementation plan.
records future implementation ownership; it does not revise accepted ADRs or This roadmap does not revise accepted ADRs.
declare the model implemented.

View File

@@ -2,13 +2,14 @@
Reviewed baseline: `01b08e76a3fecc22c4414437bfeaa07b4b7a85aa`. Reviewed baseline: `01b08e76a3fecc22c4414437bfeaa07b4b7a85aa`.
Status: four open findings. This is an audit record, not an implementation plan. Status: all four findings resolved. This remains an audit record, not an
No production code or repository tests were changed. implementation plan; resolution evidence is recorded with each finding.
The [interface remediation roadmap](interface-remediation.md) describes the The [interface remediation roadmap](interface-remediation.md) describes the
settled target, required changes, and dependencies, including a shared internal settled target and its dependencies, including a shared internal history model
history model for metadata history and explanation. Implementation remains pending. for metadata history and explanation. The completed implementation and
This audit retains the findings and reproduction evidence. integrated validation are recorded in [implementation.md](implementation.md).
This audit retains the findings and original reproduction evidence.
## Scope and evidence ## Scope and evidence
@@ -36,7 +37,9 @@ existing contracts rather than introduce new API restrictions or guarantees.
## 1. Resolution presence queries confuse explicit keys with sequence indexes ## 1. Resolution presence queries confuse explicit keys with sequence indexes
Priority: P2. Status: open. Priority: P2. Status: resolved. Evidence: `TestFacadeResolutionPresenceUsesDynamicEntryShape`,
the engine resolution/provenance/default regressions, and the integrated checks
recorded in [implementation.md](implementation.md).
Relevant code: Relevant code:
@@ -82,7 +85,9 @@ documented treatment of invalid schema paths.
## 2. Resolution can transfer explicitness to a different semantic path ## 2. Resolution can transfer explicitness to a different semantic path
Priority: P2. Status: open. Priority: P2. Status: resolved. Evidence: the engine resolution/metadata/provenance
regressions, the full engine suite, and the integrated checks recorded in
[implementation.md](implementation.md).
Relevant code: `applyResolutionMetadata`, `applyResolutionFieldOrigins`, and Relevant code: `applyResolutionMetadata`, `applyResolutionFieldOrigins`, and
`refreshResolutionFields` in `refreshResolutionFields` in
@@ -122,7 +127,10 @@ repair this publication path.
## 3. Metadata history mixes numeric-key and sequence-index definitions ## 3. Metadata history mixes numeric-key and sequence-index definitions
Priority: P2. Status: open. Priority: P2. Status: resolved. Evidence: `TestPublicHistoryUsesResolutionShapeAttribution`,
`TestPublicHistoricalPathsEnumerateContextualShapes`, shared history-selection
and explanation regressions, and the integrated checks recorded in
[implementation.md](implementation.md).
Relevant code: Relevant code:
@@ -163,7 +171,9 @@ and compare metadata history with explanation.
## 4. Diagnostic canonicalization breaks composition claimant ordering ## 4. Diagnostic canonicalization breaks composition claimant ordering
Priority: P3. Status: open. Priority: P3. Status: resolved. Evidence: `TestFacadeCompositionConflictKeepsClaimantOrder`,
the engine diagnostic-order regression, and the integrated checks recorded in
[implementation.md](implementation.md).
Relevant code: `compositionConflictDiagnostic` in Relevant code: `compositionConflictDiagnostic` in
[compose.go](../../internal/engine/compose.go) and `canonicalDiagnostics` in [compose.go](../../internal/engine/compose.go) and `canonicalDiagnostics` in

View File

@@ -47,8 +47,18 @@ func TestFacadeCompositionConflictKeepsClaimantOrder(t *testing.T) {
} }
pathsByID := make(map[string]string) pathsByID := make(map[string]string)
var acquisitionOrder []string
for _, source := range loadError.Sources() { for _, source := range loadError.Sources() {
pathsByID[source.ID] = source.Path pathsByID[source.ID] = source.Path
for _, name := range []string{"z.yml", "b.yml", "c.yml"} {
if source.Path == name || strings.HasSuffix(source.Path, "/"+name) {
acquisitionOrder = append(acquisitionOrder, strings.TrimSuffix(name, ".yml"))
break
}
}
}
if strings.Join(acquisitionOrder, ",") != "z,b,c" {
t.Fatalf("claimant acquisition order = %v, want z,b,c", acquisitionOrder)
} }
claimant := func(location configkit.Location) string { claimant := func(location configkit.Location) string {
for _, name := range []string{"b.yml", "c.yml", "z.yml"} { for _, name := range []string{"b.yml", "c.yml", "z.yml"} {

View File

@@ -237,8 +237,8 @@ func TestApplyResolutionMetadataPreservesOverlappingDeltaOrder(t *testing.T) {
effectivePaths: effectivePathIndex(before), effectivePaths: effectivePathIndex(before),
}} }}
resolved := resolutionResult{ resolved := resolutionResult{
final: final, final: final,
deltas: []documentDelta{{path: Keys("group")}, {path: Keys("group", "item")}}, deltas: []documentDelta{{path: Keys("group")}, {path: Keys("group", "item")}},
snapshots: snapshots, snapshots: snapshots,
} }