diff --git a/docs/development.md b/docs/development.md index e7064ae..bb74b59 100644 --- a/docs/development.md +++ b/docs/development.md @@ -232,6 +232,7 @@ code changes. Use the component overview to find the corresponding implementatio | Effective configuration diff | [Engine comparison and masking tests](../internal/engine/diff_test.go), [engine operation tests](../internal/engine/diff_operation_test.go), [root facade tests](../facade_diff_test.go), and [consumer examples](../examples/consumers/diff_test.go) | `go test ./internal/engine -run 'Diff|Explain|History|Secret|Independent'`, `go test . -run 'Diff|FacadeInspection|PublicFacadeBoundary|DependencyImportBoundary'`, `go test ./examples/consumers`, and `go test . -run '^ExampleDiff$'` | | Consumer examples and migration fixtures | [Consumer tests](../examples/consumers/consumers_test.go), [native, layered, and ordinary relative-import examples](../examples/consumers/layered_test.go), [mounted collection examples](../examples/consumers/destinations_test.go), [API examples](../example_test.go) | `go test ./examples/consumers` and `go test . -run '^Example'` | | Assembly and layered scaling evidence | [Assembly benchmarks](../internal/engine/assembly_bench_test.go), [layered benchmarks](../internal/engine/underlay_bench_test.go) | `go test ./internal/engine -run '^$' -bench '^BenchmarkUnderlay' -benchmem`; repeat with `^BenchmarkCompose` and `^BenchmarkOverlay` | +| Identified-sequence scaling evidence | [Mixed-upsert benchmark](../internal/engine/sequence_combine_bench_test.go) | `go test ./internal/engine -run '^$' -bench '^BenchmarkSequenceMixedUpsert$' -benchmem` | | Inheritance scaling evidence | [Expansion benchmarks](../internal/engine/inheritance_bench_test.go) | `go test ./internal/engine -run '^$' -bench '^BenchmarkInheritance' -benchmem` | | Documentation links and dependency isolation | [Link checks](../documentation_test.go), [import boundary](../import_boundary_test.go), [public boundary](../public_boundary_test.go) | `go test . -run 'TestLocalDocumentationLinks\|TestDependencyImportBoundary\|TestPublicFacadeBoundary'` | | Development check behavior | [Development checker test](../development_check_test.go) | `go test . -run '^TestDevelopmentCheckHandlesFilenamesAndStopsOnFailure$'` | diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index d8763f5..b91ce9a 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Sequence Identity And Combination Implementation Plan -Status: implementation in progress; Stages 1–29 complete. +Status: all thirty stages complete. Audience: a Luna coding agent implementing one numbered stage per prompt, in order. This plan starts at commit @@ -1031,6 +1031,37 @@ from Stages 28–29 if their covered content is unchanged. Record completed scop validation, benchmark commands/qualitative findings, and any real remaining issues accurately. No new timing thresholds or release gates are introduced. +**Completion:** Audited the shared indexed sequence-combination and identity +validation paths, declaration gathering, numeric normalization, ownership and +selector-path handling, adapters, dependencies, boundaries, and limits. Removed +per-declaration temporary-slice allocation while retaining detached declaration +ownership. Added a mixed-size identified-sequence upsert benchmark because the +existing assembly benchmarks did not exercise this path. Its allocations grew +roughly in proportion to record count from 128 to 2,048 records; elapsed times +were similarly proportional in this short run and are descriptive only. + +Benchmark command: + +```sh +go test ./internal/engine -run '^$' -bench '^(BenchmarkComposeWideMappings|BenchmarkUnderlay(BroadCatalog|ManySmallTiers)|BenchmarkOverlay(RecursiveMappings|ManyApplications)|BenchmarkInheritance(Expansion|IndependentScopes)|BenchmarkSequenceMixedUpsert)$' -benchmem -benchtime=100ms +``` + +The benchmark reported mixed-upsert results of 278,009 B and 2,337 allocations +per operation at 128 records; 1,122,177 B and 9,253 allocations at 512; and +4,521,839 B and 36,925 allocations at 2,048. No thresholds are implied. The +code review found shared combination and identity algorithms, indexed matching +and mapping access, declaration grouping by destination, coefficient/exponent +numeric normalization without magnitude expansion, operation-local ownership +and selector traversal, no remaining early-CLI adapter, and no newly introduced +dependencies, public internal types, background work, release machinery, or +sequence-specific resource limits. Obsolete registration names remain only in +historical or roadmap text. + +Verified with `./scripts/check.sh`, `go test -race ./...`, +`go test . -run 'TestLocalDocumentationLinks|TestDependencyImportBoundary|TestPublicFacadeBoundary' -count=1`, +`git diff --check`, and the benchmark command above. No remaining implementation +issues were found. + Acceptance: all roadmap operations and lifecycle boundaries work through ordinary and layered loads; values and inspection agree; application constraints hold on successful final results; deferred behavior and YAML-only guarantees have not diff --git a/internal/engine/imports.go b/internal/engine/imports.go index eb0a4a3..a9eb140 100644 --- a/internal/engine/imports.go +++ b/internal/engine/imports.go @@ -812,11 +812,11 @@ func (s *importTraversal) composePendingItems(scope *acquisitionScope, policy se func acquiredSequenceDeclarations(scope acquisitionScope) []sequenceDeclarationSpec { var declarations []sequenceDeclarationSpec for _, contribution := range scope.contributions { - for _, declaration := range contribution.sequenceDeclarations { - projected := cloneSequenceDeclarations([]sequenceDeclarationSpec{declaration})[0] - projected.destination = appendDestination(contribution.relativeDestination, declaration.destination) - declarations = append(declarations, projected) + projected := cloneSequenceDeclarations(contribution.sequenceDeclarations) + for index := range projected { + projected[index].destination = appendDestination(contribution.relativeDestination, projected[index].destination) } + declarations = append(declarations, projected...) } return declarations } diff --git a/internal/engine/sequence_combine_bench_test.go b/internal/engine/sequence_combine_bench_test.go new file mode 100644 index 0000000..f0cc8fa --- /dev/null +++ b/internal/engine/sequence_combine_bench_test.go @@ -0,0 +1,42 @@ +package engine + +import ( + "strconv" + "testing" + + "gitea.maximumdirect.net/eric/ConfigKit/internal/document" +) + +func BenchmarkSequenceMixedUpsert(b *testing.B) { + for _, size := range []int{128, 512, 2048} { + b.Run(strconv.Itoa(size), func(b *testing.B) { + lower := benchmarkSequenceRecords(0, size, "lower") + higher := benchmarkSequenceRecords(size/2, size, "higher") + context := sequenceCombinationContext{destination: Keys("items")} + identityFields := []string{"id"} + b.ReportAllocs() + b.ResetTimer() + for range b.N { + if _, diagnostics := combineIdentifiedSequences( + lower, higher, sequenceModeUpsert, identityFields, context, + ); len(diagnostics) != 0 { + b.Fatal(diagnostics) + } + } + }) + } +} + +func benchmarkSequenceRecords(start, count int, value string) *document.Node { + items := make([]*document.Node, count) + for index := range count { + items[index] = &document.Node{ + Kind: document.Mapping, + Mapping: []document.Entry{ + {Key: "id", Value: &document.Node{Kind: document.String, Text: "item-" + strconv.Itoa(start+index)}}, + {Key: "value", Value: &document.Node{Kind: document.String, Text: value}}, + }, + } + } + return &document.Node{Kind: document.Sequence, Sequence: items} +}