From cb5b4356aad2d3de6c04cdea4393b529b43a4285 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Mon, 7 Sep 2026 01:19:00 +0000 Subject: [PATCH] Complete ownership documentation and integration validation --- docs/internal/extraction.md | 5 ++- docs/internal/overview.md | 25 ++++++++----- docs/roadmap/implementation.md | 12 ++++-- docs/roadmap/remediation.md | 67 +++++++++++++++++++++++++++------- resolution.go | 17 +-------- 5 files changed, 83 insertions(+), 43 deletions(-) diff --git a/docs/internal/extraction.md b/docs/internal/extraction.md index c1c63f3..a4e064e 100644 --- a/docs/internal/extraction.md +++ b/docs/internal/extraction.md @@ -115,8 +115,9 @@ Assigned to explicit import traversal and glob handling: Canonical paths—not `os.SameFile`—define identity, so hard links remain distinct. Path-import implementation record (2026-09-06): `splitImportDirectives`, -`parseImportDeclaration`, `importFilesystem`, `importTraversal.visitPath`, and -`loadImportedDocuments` in `imports.go` adapt the assigned envelope, loading, source, +`parseImportDeclaration` (now in `directives.go`), `importFilesystem` (now in +`filesystem.go`), and `importTraversal.visitPath`/`loadImportedDocuments` in +`imports.go` adapt the assigned envelope, loading, source, and failure mechanics. The corresponding ConfigKit tests adapt the assigned declaration-order, disjoint composition, keyed-entry, all-source conflict, unsafe target, alias, imported parse/schema, and relative-resolution cases. ConfigKit adds diff --git a/docs/internal/overview.md b/docs/internal/overview.md index 42404f3..e8f3784 100644 --- a/docs/internal/overview.md +++ b/docs/internal/overview.md @@ -1,10 +1,11 @@ # Internal Component Overview -ConfigKit currently contains the root `configkit` package, which establishes the -module and package documentation boundary. Its implemented public primitives are: +ConfigKit exposes the root `configkit` package and keeps its document and YAML +representations private. The implemented components and their owners are: - immutable semantic `Path` construction and strict JSON Pointer parsing; -- detached provenance and diagnostic record types with empty `Metadata` queries; +- detached effective presence/origin and chronological history queries in + `metadata.go`, with provenance and diagnostic record types; - canonical, control-safe diagnostic rendering and structured `LoadError` access; - opaque file, byte, reader, and no-input source construction in `source.go`, with shared regular-file checks and bounded read mechanics in `source_file.go`; @@ -33,11 +34,10 @@ module and package documentation boundary. Its implemented public primitives are baseline/final trees, and initial default/input origins; - public lifecycle coordination in `load.go`, option selection in `options.go`, input assembly in `load_input.go`, typed phases/publication in `load_result.go`, - bounded canonical import DFS in - `imports.go`, filesystem context/containment in `filesystem.go`, directive - parsing/restrictions in `directives.go`, pattern-directed glob expansion in - `glob.go`, version-report contexts - in `validation.go`, and detached layered metadata/history assembly in + bounded canonical import DFS in `imports.go`, filesystem context/containment in + `filesystem.go`, directive parsing/restrictions in `directives.go`, + pattern-directed glob expansion in `glob.go`, schema-version checking and report + contexts in `validation.go`, and layered metadata/history assembly in `load_metadata.go`; - recorded application defaulting and normalization in `resolution.go`, including explicitness queries, helper verification, structural mutation audit, coalesced @@ -50,7 +50,8 @@ module and package documentation boundary. Its implemented public primitives are - explicit bounded startup environment bootstrap and safe partial reporting in `secrets.go`; - fixed-point tag/predicate/dependency sensitivity classification in `secret.go`; -- frozen-snapshot redaction and canonical effective output in `render.go`; +- canonical effective output in `render.go`, using frozen-snapshot redaction + shared with explanation in `snapshot.go`; - detached public explanation records and coordination in `explain.go`, immutable input applications/replay and retained-node budgeting in `history.go`, shared safe snapshot projection in `snapshot.go`, and deterministic human output in @@ -61,6 +62,12 @@ module and package documentation boundary. Its implemented public primitives are - a fail-fast source-candidate checker in `scripts/release-check.sh`, with local documentation-link and public import-boundary gates owned by root-package tests. +Dependency direction remains inward: the public lifecycle coordinates private +source, document, schema, and inspection helpers. Semantic paths stay in the root +package; `internal/document` owns only representation and cloning and never imports +the root package. Only `internal/yaml` imports the upstream YAML package. Maintained +consumer examples use the public package and standard library. + The [configuration contract](../config.md) owns implemented input, schema, decoding, loading lifecycle, path imports, composition, profile/CLI overlay, version checking, recorded resolution, typed secret references/bootstrap, semantic validation, diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 5a41172..6eb0dd2 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -517,7 +517,8 @@ Status: complete. Completion evidence (2026-09-06): - Added descriptor-driven canonical typed projection and independently owned cloning - in [`projection.go`](../../projection.go), without YAML serialization or a second + in [`projection.go`](../../projection.go) (cloning now lives in + [`clone.go`](../../clone.go)), without YAML serialization or a second binding model. Zero values, nil/empty distinctions, exact integers, destination- precision finite floats, durations, text scalars, dynamic concrete values, and recursive acyclic objects retain their configuration meaning. @@ -1306,7 +1307,9 @@ Status: complete. Completion evidence (2026-09-06): - Activated the existing `Override`/`Options.Overrides` surface through the new - parser-neutral implementation in [`override.go`](../../override.go). It accepts + parser-neutral implementation in [`override.go`](../../override.go) (value + building now lives in [`override_value.go`](../../override_value.go), application + in [`override_apply.go`](../../override_apply.go)). It accepts only built-in scalar values, `nil`, `[]any`, and `map[string]any`; preserves scalar kinds and sequence order; sorts maps; rejects named/unsupported values, nonfinite floats and cycles; and snapshots all accepted caller-owned state without @@ -1371,7 +1374,10 @@ Completion evidence (2026-09-06): - Added detached `ValueSnapshot`, `ValueChange`, `SecretReferenceInfo`, and `Explanation` records plus `Result.Explain` and `Result.WriteExplanation` in - [`explain.go`](../../explain.go). Effective/default/domain values use canonical + [`explain.go`](../../explain.go) (human rendering now lives in + [`explain_render.go`](../../explain_render.go); replay and snapshots in + [`history.go`](../../history.go) and [`snapshot.go`](../../snapshot.go)). + Effective/default/domain values use canonical typed projection; base/profile/CLI events preserve policy-validated input, with explicit absent, null, equal-write, replacement, and deletion states. - Extended composition, profile, and CLI handling to retain immutable applications diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md index 6b813ef..48560d0 100644 --- a/docs/roadmap/remediation.md +++ b/docs/roadmap/remediation.md @@ -2,7 +2,8 @@ ## Status and scope -Status: in progress; completed stages and their validation are recorded below. +Status: complete; all nine stages are implemented and validated below. +Release-candidate selection and publication remain separate maintainer work. Audit baseline: `9b147bfd96aec25e0125dcae66e136e56dc7a670`. This roadmap owns the agreed maintainability cleanup before v0.1.0. It replaces @@ -56,8 +57,9 @@ Use focused existing behavioral tests during each stage and the baseline checks from the development guide before committing production changes. Add tests only for meaningful gaps exposed by extraction, not to enforce file locations or private call choreography. Update current owning documentation alongside each -move. Planned filenames below are private implementation destinations, not new -consumer contracts. +move. The work lists below preserve the accepted scope; completion entries name +the implemented owners. Audit-baseline evidence describes the original layout. +Private implementation destinations are not new consumer contracts. ## Stage 1 — Remove unused overlay value snapshots @@ -69,7 +71,7 @@ that resolution snapshots and history applications have separate live consumers; those and displaced origins remain intact. The full offline test suite, vet, build, and whitespace checks passed with Go 1.26.7 on Linux/amd64. -Evidence: `overlayRecord` in [overlay.go](../../overlay.go) retains `before` and +Audit-baseline evidence: `overlayRecord` in [overlay.go](../../overlay.go) retains `before` and `after` trees; profile and CLI processing construct them and `cloneOverlayRecords` clones them. Production consumers use the record's change and displaced origins, while explanation uses `historyApplication` instead. @@ -100,7 +102,7 @@ safe selected-source errors and imported/profile source attribution, so no duplicate regression was added. Full offline tests, vet, build, and whitespace checks passed with Go 1.26.7 on Linux/amd64. -Evidence: [parse.go](../../parse.go) translates adapter issues inline, while +Audit-baseline evidence: [parse.go](../../parse.go) translates adapter issues inline, while `importParseDiagnostics` in [imports.go](../../imports.go) repeats the translation for imports and profiles. @@ -129,7 +131,7 @@ limit diagnostics. Existing filesystem, FIFO, budget, and reader tests pass; a private regression covers nondeterministic filesystem failure phases. Full offline baseline and race suites passed with Go 1.26.7 on Linux/amd64. -Evidence: `readSource`, `importTraversal.readImport`, and `readProfileFile` repeat +Audit-baseline evidence: `readSource`, `importTraversal.readImport`, and `readProfileFile` repeat preflight stat, open, post-open stat, regular-file checks, size checks, and bounded reads in [source.go](../../source.go), [imports.go](../../imports.go), and [profile.go](../../profile.go). @@ -172,10 +174,10 @@ remain explicit. Full offline tests (including historical path shapes, metadata detachment, and dynamic secrets), vet, build, and whitespace checks passed with Go 1.26.7 on Linux/amd64. -Evidence: `indexDocument`, `walkDocumentPaths`, and `projectedSensitivity` repeat +Audit-baseline evidence: `indexDocument`, `walkDocumentPaths`, and `projectedSensitivity` repeat semantic tree traversal in [load_metadata.go](../../load_metadata.go), [metadata.go](../../metadata.go), and [secret.go](../../secret.go). General document -lookup currently lives in [load.go](../../load.go). +lookup lived in [load.go](../../load.go). Work: @@ -215,7 +217,7 @@ Full offline baseline and race suites passed with Go 1.26.7 on Linux/amd64, including codec/cycle/limit, callback ownership, sensitivity, and secret-state regressions. -Evidence: [projection.go](../../projection.go) combines roughly 622 lines of +Audit-baseline evidence: [projection.go](../../projection.go) combines roughly 622 lines of projection, detached cloning, dynamic schema handling, cycle/limit enforcement, and structural comparison. Value equality deliberately ignores sensitivity, which validation must check separately. @@ -260,7 +262,7 @@ preserves primary failures and explicitly checks the success-path close once. Full offline tests, vet, build, and whitespace checks passed with Go 1.26.7 on Linux/amd64, including imports/globs, profiles, CLI, limits, and provenance. -Evidence: [imports.go](../../imports.go) mixes filesystem context, directives, +Audit-baseline evidence: [imports.go](../../imports.go) mixes filesystem context, directives, graph traversal, and diagnostics; [override.go](../../override.go) combines value construction/validation and application. Shared composition cloning is located inside the override feature, while profile overlay repeats it. @@ -304,7 +306,7 @@ clones remain, and publication adds no history copies. Full offline baseline and race suites passed with Go 1.26.7 on Linux/amd64; lifecycle, early-stop, warning, precedence, provenance, callback ownership, and secret tests passed unchanged. -Evidence: `loadWithSecretLookup` in [load.go](../../load.go) coordinates roughly +Audit-baseline evidence: `loadWithSecretLookup` in [load.go](../../load.go) coordinates roughly 200 lines of source assembly, decoding, callbacks, history, secrets, and result publication, including repeated creation of a composition handoff. @@ -349,7 +351,7 @@ container/leaf, retained-budget, detachment, and writer-failure tests passed without expectation changes. Full offline tests, vet, build, and whitespace checks passed with Go 1.26.7 on Linux/amd64. -Evidence: [explain.go](../../explain.go) combines approximately 576 lines of public +Audit-baseline evidence: [explain.go](../../explain.go) combines approximately 576 lines of public records, replay algorithms, snapshot redaction, retained-history accounting, and human-readable output. @@ -376,7 +378,46 @@ leaf histories still reconcile with the frozen effective typed configuration. ## Stage 9 — Complete ownership documentation and integration validation -Status: pending. +Status: complete. + +Completion evidence (2026-09-07): + +- Reviewed the final owners and accumulated diff against starting revision + `874adaa`. Removed the unused `cloneResolutionSnapshots` helper and an unused + resolution lookup binding; live resolution snapshots and replay budgets remain. + Shared parser translation and document walking have one owner, while specialized + origin, pruning, and shared-node accounting remain explicit. +- Updated the [component overview](../internal/overview.md), repaired moved-owner + navigation in the extraction and implementation records, and distinguished + baseline findings from completion evidence here. The overview now accurately + describes populated metadata queries and the retained dependency direction. +- An independent Go AST comparison found all 186 root-package exported + declarations unchanged from `874adaa`. Function-level review ignoring file moves + matched the planned extractions, consolidation, and private renames. Existing + behavioral assertions remain unchanged; no API, configuration, diagnostic, + dependency, or consumer migration change was identified. +- The complete source checker passed on native Linux/amd64 with CGO enabled, + using these exact cached toolchains: + + ```sh + CONFIGKIT_BASELINE_TOOLCHAIN=go1.25.5 CONFIGKIT_NEWER_TOOLCHAIN=go1.26.7 ./scripts/release-check.sh + ``` + + This ran offline default tests, vet, and native builds on Go 1.25.5 and Go 1.26.7; + the full race suite on Go 1.26.7; disposable-copy module hygiene; formatting and + whitespace; executable examples and consumer fixtures; local documentation + links and the AST import-boundary gate; and CGO-disabled cross-builds for + Linux/macOS on amd64/arm64. All passed; `go.mod` and `go.sum` are unchanged. +- Fresh verbose Linux filesystem checks passed without skips for selected/imported/ + profile FIFO rejection, symlink containment, hard-link identity, optional missing + targets, directory permission failures, and the new private read-failure phase + regression. Package import inspection confirmed `internal/document` has no + imports and only `internal/yaml` imports the upstream YAML package. +- Native macOS and native arm64 execution were unavailable on this Linux/amd64 + host. Cross-builds do not close those execution gaps. Exact candidate validation, + roadmap retirement, release-note review, remote/tag guards, and post-publication + retrieval remain owned by the [release procedure](../release.md) and + [readiness record](release-readiness.md). No tag, push, or publication occurred. Work: diff --git a/resolution.go b/resolution.go index 6e507a3..1373010 100644 --- a/resolution.go +++ b/resolution.go @@ -249,7 +249,7 @@ func runResolution[T any](configuration *T, resolver func(*T, *Resolution) error } } for _, record := range ordered { - beforeNode, beforePresent := documentAtPath(decoded.final, record.path) + _, beforePresent := documentAtPath(decoded.final, record.path) afterNode, afterPresent := documentAtPath(after, record.path) if !beforePresent && !afterPresent { state.addDiagnostic(CodeResolveInvalidRecord, record.path, "resolution record does not identify an existing or removed value") @@ -258,7 +258,6 @@ func runResolution[T any](configuration *T, resolver func(*T, *Resolution) error if record.helperExpected != nil && (!afterPresent || !configurationValuesEqual(record.helperExpected, afterNode)) { state.addDiagnostic(CodeResolveInvalidTarget, record.path, "resolution helper assignment does not match its declared configuration path") } - _ = beforeNode } if hasErrors(state.diagnostics) { return resolutionResult{diagnostics: canonicalDiagnostics(state.diagnostics)} @@ -343,17 +342,3 @@ func clonePaths(paths []Path) []Path { } return cloned } - -func cloneResolutionSnapshots(snapshots []resolutionSnapshot) []resolutionSnapshot { - if snapshots == nil { - return nil - } - cloned := make([]resolutionSnapshot, len(snapshots)) - for index, snapshot := range snapshots { - cloned[index] = resolutionSnapshot{ - change: cloneChange(snapshot.change), - before: document.Clone(snapshot.before), after: document.Clone(snapshot.after), - } - } - return cloned -}