diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index 01d79f09..89e5621f 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -20,14 +20,20 @@ version, custom merging, path-containment rule, template exemption, or release gate. The newly reserved `extends` key is the expressly adopted upstream compatibility change. -Two follow-ups remain: a path-test blind spot and an incomplete documented -command. This document records remediation work only; it does not authorize +Two follow-ups were identified: a path-test blind spot and an incomplete +documented command. Completion is recorded under each finding. This document +records remediation work only; it does not authorize unrelated runtime refactoring. ## Finding 1 — Make The Path Fixture Distinguish Declaring Directories Priority: P2. Category: verification gap. +Status: addressed on 2026-10-04. The fixture now uses distinct parent-, child-, +and overlay-local paths for the source-base assertions and retains a separate +`../` reference. `GOWORK=off go test ./internal/core/config` passed. No +production resolver change was needed. + Evidence: `internal/core/config/inheritance_test.go:338–436`, `TestInheritedReferencePathsKeepDeclaringSource`. @@ -93,5 +99,5 @@ the CLI reference and existing parser coverage without a live model request. - The implementation diff passed whitespace checks. - The incomplete development invocation was reproduced without provider calls. -The passing suite establishes the current tested behavior; it does not resolve -the path-fixture blind spot identified above. +These checks describe the review baseline. Subsequent remediation and its +focused validation are recorded under each finding. diff --git a/internal/core/config/inheritance_test.go b/internal/core/config/inheritance_test.go index fde19fe6..e462f740 100644 --- a/internal/core/config/inheritance_test.go +++ b/internal/core/config/inheritance_test.go @@ -347,8 +347,15 @@ func TestInheritedReferencePathsKeepDeclaringSource(t *testing.T) { t.Fatal(err) } } - for _, name := range []string{"shared.txt", "parent.txt", "child.txt", "step.txt", "overlay.txt"} { - if err := os.WriteFile(filepath.Join(fixtureDirectory, name), []byte("fixture\n"), 0o600); err != nil { + for _, fixture := range []struct{ directory, name string }{ + {parentDirectory, "shared.txt"}, + {parentDirectory, "parent.txt"}, + {parentDirectory, "step.txt"}, + {childDirectory, "child.txt"}, + {overlayDirectory, "overlay.txt"}, + {fixtureDirectory, "outside.txt"}, + } { + if err := os.WriteFile(filepath.Join(fixture.directory, fixture.name), []byte("fixture\n"), 0o600); err != nil { t.Fatal(err) } } @@ -358,14 +365,15 @@ func TestInheritedReferencePathsKeepDeclaringSource(t *testing.T) { " parent ": input: {module: input} references: - " shared ": {path: ../fixtures/shared.txt} + " shared ": {path: ./shared.txt} nested: extends: " shared " - source: {path: ../fixtures/parent.txt} + source: {path: ./parent.txt} + outside: {path: ../fixtures/outside.txt} steps: - id: first references: - step-source: {path: ../fixtures/step.txt} + step-source: {path: ./step.txt} artifacts: summary: extract: {module: extract} @@ -377,7 +385,7 @@ func TestInheritedReferencePathsKeepDeclaringSource(t *testing.T) { child: extends: " parent " references: - source: {path: ../fixtures/child.txt} + source: {path: ./child.txt} `), 0o600); err != nil { t.Fatal(err) } @@ -393,7 +401,7 @@ configkit: if err := os.WriteFile(filepath.Join(overlayDirectory, "development.yml"), []byte(`pipelines: " parent ": references: - " shared ": {path: ../fixtures/overlay.txt} + " shared ": {path: ./overlay.txt} `), 0o600); err != nil { t.Fatal(err) } @@ -408,12 +416,14 @@ configkit: t.Errorf("%s reference %s path = %q, want %q", pipelineID, referenceID, got, want) } } - assertReferencePath("parent", "shared", filepath.Join(fixtureDirectory, "shared.txt")) - assertReferencePath("child", "shared", filepath.Join(fixtureDirectory, "shared.txt")) - assertReferencePath("child", "nested", filepath.Join(fixtureDirectory, "shared.txt")) - assertReferencePath("parent", "source", filepath.Join(fixtureDirectory, "parent.txt")) - assertReferencePath("child", "source", filepath.Join(fixtureDirectory, "child.txt")) - if got := loaded.Config.Pipelines["child"].Steps[0].References["step-source"].Path; got != filepath.Join(fixtureDirectory, "step.txt") { + assertReferencePath("parent", "shared", filepath.Join(parentDirectory, "shared.txt")) + assertReferencePath("child", "shared", filepath.Join(parentDirectory, "shared.txt")) + assertReferencePath("child", "nested", filepath.Join(parentDirectory, "shared.txt")) + assertReferencePath("parent", "source", filepath.Join(parentDirectory, "parent.txt")) + assertReferencePath("child", "source", filepath.Join(childDirectory, "child.txt")) + // Keep ../ coverage separate from paths that distinguish the declaring file. + assertReferencePath("child", "outside", filepath.Join(fixtureDirectory, "outside.txt")) + if got := loaded.Config.Pipelines["child"].Steps[0].References["step-source"].Path; got != filepath.Join(parentDirectory, "step.txt") { t.Errorf("inherited step reference path = %q", got) } @@ -423,15 +433,15 @@ configkit: } for _, pipelineID := range []string{"parent", "child"} { for _, referenceID := range []string{"shared", "nested"} { - if got, want := overlaid.Config.Pipelines[pipelineID].References[referenceID].Path, filepath.Join(fixtureDirectory, "overlay.txt"); got != want { + if got, want := overlaid.Config.Pipelines[pipelineID].References[referenceID].Path, filepath.Join(overlayDirectory, "overlay.txt"); got != want { t.Errorf("overlaid %s reference %s path = %q, want %q", pipelineID, referenceID, got, want) } } } - if got, want := overlaid.Config.Pipelines["child"].References["source"].Path, filepath.Join(fixtureDirectory, "child.txt"); got != want { + if got, want := overlaid.Config.Pipelines["child"].References["source"].Path, filepath.Join(childDirectory, "child.txt"); got != want { t.Errorf("child replacement path = %q, want %q", got, want) } - if got, want := overlaid.Config.Pipelines["child"].Steps[0].References["step-source"].Path, filepath.Join(fixtureDirectory, "step.txt"); got != want { + if got, want := overlaid.Config.Pipelines["child"].Steps[0].References["step-source"].Path, filepath.Join(parentDirectory, "step.txt"); got != want { t.Errorf("overlaid inherited step reference path = %q, want %q", got, want) } }