From 8645cab79aec748d480374924e1e964e8128db7d Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Thu, 15 Oct 2026 15:02:50 +0000 Subject: [PATCH] Record shared source version policy --- docs/adr/0013-shared-source-version-checks.md | 89 +++++++++++++++++++ docs/development.md | 1 + docs/roadmap/implementation.md | 11 ++- docs/roadmap/source-version-checks.md | 3 +- 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 docs/adr/0013-shared-source-version-checks.md diff --git a/docs/adr/0013-shared-source-version-checks.md b/docs/adr/0013-shared-source-version-checks.md new file mode 100644 index 0000000..8b9b8fa --- /dev/null +++ b/docs/adr/0013-shared-source-version-checks.md @@ -0,0 +1,89 @@ +# ADR 0013: Check Source Versions with One Shared Policy + +## Status + +Accepted. The [shared source-version roadmap](../roadmap/source-version-checks.md) +owns target behavior, and its [implementation plan](../roadmap/implementation.md) +owns delivery status and sequencing. + +## Date + +2026-10-15 + +## Context + +Applications that assemble one configuration from independently authored +documents need a way to require that each contributing document declares a +version accepted by the application's existing `Definition.Version` checker. +Checking only the eventual composed value lets another source hide a rejected +declaration, while separate consumer-side parsing duplicates ConfigKit's source +handling and diagnostics. + +The extension must preserve one application-owned acceptance policy and the +existing loading lifecycle. Source declarations are compatibility evidence, not +independent fragment schemas or values to compare for equality. Existing +composition, placement, precedence, source identity, diagnostics, and +sensitivity rules remain authoritative. + +## Decision + +Provide a load-wide source-version mode for ordinary and layered loading. The +zero-value mode preserves current behavior. The enabled modes check declarations +when present or require them, using the existing `Definition.Version` path and +checker. Interpret the configured path relative to each participating source +before placement or composition. Different declarations may be accepted by the +same checker; ConfigKit adds no equality, SemVer, or expected-version rule. + +Apply the selected policy to the actual main document, direct underlays, +imports, and selected overlays. Missing non-main declarations are skipped in +if-present mode and rejected in required mode. Existing main absence behavior +remains, with required mode additionally rejecting an absent declaration on an +actual main document. `NoSource`, unmatched optional inputs, synthetic field +operations, and empty groups do not become documents that need declarations. + +Reuse the existing version vocabulary and validation boundary: absence, null, +exact strings, and strict decimal integers retain their established meanings; +unsupported present values fail version-type validation. Warnings remain +nonfatal, and source declarations do not replace final application decoding or +domain validation. + +After an accepted non-main declaration is checked, consume exactly that node +before its remaining application content is composed or overlaid. Preserve the +main declaration and its value semantics. Keep the declaration, source-local +path, physical location, and checked absence as detached source evidence, +separate from effective application values and history. Apply established +sensitivity rules to that evidence, including original mounted paths and +ancestors; retain existing safe failure disclosure. + +In enabled modes, the main declaration remains source-local while its protected +application path is derived from the main input's destination. This distinction +does not change default-mode path interpretation or weaken protection of +remaining payload and synthetic operations. + +Public option-field additions and the enabled-mode interpretation for mounted +main inputs are compatibility considerations for separately authorized minor- +release preparation. This decision does not select a release version or +authorize release notes or publication. + +## Alternatives Considered + +- **Check only the final composed value.** Later sources can hide an earlier + rejected declaration, so this does not validate every contributing document. +- **Let consumers parse and check each source.** This duplicates acquisition, + source attribution, safe diagnostics, and lifecycle coordination in every + application. +- **Require declarations to be equal or impose a universal version grammar.** + Consumers already own the acceptance policy; ConfigKit need not invent an + expected value or a domain-specific compatibility rule. +- **Keep accepted non-main declarations in application payload.** A selected + source-local declaration is metadata for this policy and cannot also remain + an ordinary field at the same path without ambiguity. + +## Consequences + +Consumers can apply one existing version policy across contributing documents +and select gradual or required adoption per load. Accepted non-main headers no +longer participate in application composition; their inspectable evidence is +kept separate and subject to sensitivity classification. Default callers retain +current behavior. The implementation plan records the concrete API names, +integration order, and validation evidence. diff --git a/docs/development.md b/docs/development.md index a1e7679..827ea48 100644 --- a/docs/development.md +++ b/docs/development.md @@ -50,6 +50,7 @@ public behavior. Accepted decisions: - [Separate composition and overlay](adr/0001-separate-composition-and-overlay.md) +- [Check source versions with one shared policy](adr/0013-shared-source-version-checks.md) - [Own YAML semantics behind a private parser boundary](adr/0002-own-yaml-semantics.md) - [Preserve presence and record application resolution](adr/0003-preserve-presence-and-resolution-history.md) - [Secret references and explicit bootstrap](adr/0004-secret-references-and-explicit-bootstrap.md) diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 9523d61..26e7566 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,6 +1,6 @@ # Implement shared source version checks -Status: planned; no implementation stages are complete. +Status: Stage 1 complete; runtime implementation has not started. Audience: a Luna coding agent implementing one numbered stage per prompt, in order. The [feature roadmap](source-version-checks.md) owns target behavior and @@ -219,6 +219,15 @@ git diff --check Validate: local-link test and whitespace. Done: baseline and accepted decision recorded, with no runtime changes. +Completion evidence: reviewed baseline `d9f08ff7198ad5a8fb5c49a43e7ccdad2ad0e707` +and the clean implementation worktree at `70c95bf660794809e58182d736c67c9085238705`; +confirmed ADR 0013 was unused. The everyday check passed with Go +`go1.26.8 linux/amd64` using +`GOTOOLCHAIN=local GOPROXY=off ./scripts/check.sh`. Documentation links and +whitespace are validated for this unit. No environmental limitation affected +these checks; validation was performed on Linux/amd64 only. No runtime changes +were made. + ## Stage 2 — Share version interpretation without changing defaults 1. Separate reusable value interpretation and callback reporting from checkVersion, diff --git a/docs/roadmap/source-version-checks.md b/docs/roadmap/source-version-checks.md index 03987ac..defabb5 100644 --- a/docs/roadmap/source-version-checks.md +++ b/docs/roadmap/source-version-checks.md @@ -1,6 +1,7 @@ # Shared Source Version Checks Roadmap -Status: design decisions settled; implementation has not started. The +Status: design decisions are recorded in [ADR 0013](../adr/0013-shared-source-version-checks.md); +implementation has not started. The [implementation plan](implementation.md) owns execution order, concrete API and integration decisions, and completion evidence. This roadmap develops the partially accepted source-version request in