From c63f4ff687ea8457332265a5c4a5414b1b544687 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 2 Nov 2026 00:46:56 +0000 Subject: [PATCH] Complete the document-root control migration review --- docs/roadmap/config-directives.md | 29 +++++++++++++---------------- docs/roadmap/implementation.md | 4 +++- facade_config_directives_test.go | 7 ++++++- facade_mapping_test.go | 4 ++-- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/docs/roadmap/config-directives.md b/docs/roadmap/config-directives.md index 7ac1d17..d129b50 100644 --- a/docs/roadmap/config-directives.md +++ b/docs/roadmap/config-directives.md @@ -1,8 +1,8 @@ # Document-Root Configuration Controls -Status: proposed implementation of the agreed `config` spelling and -source-document-root-only reservation. Ordinary application-root `config` data -created through placement or later lifecycle operations is permitted. +Status: implemented. The `config` spelling and source-document-root-only +reservation are in effect. Ordinary application-root `config` data created +through placement or later lifecycle operations is permitted. Planning baseline: `1e69abc88cf748537cd7febc85e0743755fa2fc1`. @@ -13,22 +13,19 @@ to use nested `config` fields for their own settings. An application that select ConfigKit adopts one control syntax; it should not need a configurable keyword or a second configuration-processing pass. -This roadmap defines the target and the work needed to reach it. The -[implementation plan](implementation.md) owns staged execution and progress. -Neither document changes current behavior. The -[configuration contract](../config.md) and public Go declarations remain -authoritative until implementation lands. +This roadmap records the target and rationale. The [implementation plan](implementation.md) +records execution and validation. The [configuration contract](../config.md) +and public Go declarations own current behavior. -## Current Baseline +## Prior Baseline -ConfigKit uses a root `configkit` mapping for `imports` and `sequences` controls. -The [directive implementation](../../internal/engine/directives.go) extracts -those controls before source placement and composition. Nested occurrences of -`configkit` are rejected, including within application mappings and sequences. -Imports-disabled and selected-overlay paths have their own checks enforcing -that reservation. +At the planning baseline, ConfigKit used a root `configkit` mapping for `imports` +and `sequences` controls, extracted before placement and composition. Nested +occurrences of `configkit` were rejected, including within application mappings +and sequences. Imports-disabled and selected-overlay paths enforced that +reservation separately. -The reservation also reaches beyond parsing: +The reservation also reached beyond parsing: - [Destination validation](../../internal/engine/destination.go) rejects `configkit` in every segment. Its helpers also serve import destinations, diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 84f31ef..8ef24b1 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Implement Document-Root Configuration Controls -Status: ready for implementation by a Luna coding agent. +Status: complete. Implementation baseline: `b27fe0598a9540ad05eefe2868a5a243eb28111e`. The [feature roadmap](config-directives.md) owns the target and its rationale; @@ -323,6 +323,8 @@ document. ## Stage 10 — Complete the integration and scope review +**Status:** Complete. Reviewed the implementation and retained old spellings in context; `./scripts/check.sh` passed with Go 1.26.8 on Linux, including formatting, whitespace, tests, vet, and build. + 1. Search current production code, tests, examples, and docs for old root controls, recursive name bans, and stale declaration paths. Review each remaining old spelling in context; retained package names, tags, error diff --git a/facade_config_directives_test.go b/facade_config_directives_test.go index 2303b4f..641810e 100644 --- a/facade_config_directives_test.go +++ b/facade_config_directives_test.go @@ -78,12 +78,14 @@ func TestDefaultsOverridesAndResolutionAtConfigRoot(t *testing.T) { Config settings `yaml:"config"` } entryExplicit := false + entryCountExplicit := false result, err := configkit.Load[app](configkit.NoSource(), configkit.Options[app]{ Definition: configkit.Definition[app]{ Defaults: func() app { return app{Config: settings{Enabled: true, Count: 2}} }, Resolve: func(value *app, r *configkit.Resolution) error { info, ok := r.EntryInfo(configkit.Keys("config", "enabled")) entryExplicit = ok && info.Explicit && info.Origin.Layer == configkit.LayerCLI + entryCountExplicit = r.IsExplicit(configkit.Keys("config", "count")) value.Config.Count = 7 r.RecordNormalization(configkit.Keys("config", "count"), "normalize count") return nil @@ -91,12 +93,15 @@ func TestDefaultsOverridesAndResolutionAtConfigRoot(t *testing.T) { }, Overrides: []configkit.Override{{Path: configkit.Keys("config", "enabled"), Value: false, Flag: "--enabled"}}, }) - if err != nil || result == nil || !entryExplicit || result.Config.Config.Enabled || result.Config.Config.Count != 7 { + if err != nil || result == nil || !entryExplicit || entryCountExplicit || result.Config.Config.Enabled || result.Config.Config.Count != 7 { t.Fatalf("result = %#v, entry explicit = %t, error = %v", result, entryExplicit, err) } if info, ok := result.Metadata().Lookup(configkit.Keys("config", "enabled")); !ok || !info.Explicit || info.Origin.Layer != configkit.LayerCLI { t.Fatalf("final enabled info = %#v, %t", info, ok) } + if info, ok := result.Metadata().Lookup(configkit.Keys("config", "count")); !ok || info.Origin.Layer != configkit.LayerResolution { + t.Fatalf("final count info = %#v, %t", info, ok) + } if _, ok := result.Explain(configkit.Keys("config", "count")); !ok { t.Fatal("missing resolution explanation") } diff --git a/facade_mapping_test.go b/facade_mapping_test.go index 5e28168..433c72a 100644 --- a/facade_mapping_test.go +++ b/facade_mapping_test.go @@ -80,8 +80,8 @@ func TestFacadeMappingImportsUseExplicitContext(t *testing.T) { "root/shared.yml": &fstest.MapFile{Data: []byte("name: imported\n")}, }) source := configkit.Mapping("programmatic", map[string]any{ - "config": map[string]any{"imports": []any{map[string]any{"path": "shared.yml"}}}, - "enabled": true, + "config": map[string]any{"imports": []any{map[string]any{"path": "shared.yml"}}}, + "enabled": true, }) result, err := configkit.Load(source, configkit.Options[mappingFacadeConfig]{ Imports: true, Filesystem: &configkit.FilesystemContext{Root: "root", BaseDir: "root", FS: &namespace},