Document shared source version checks

This commit is contained in:
2026-10-15 16:23:39 +00:00
parent 358b28c421
commit 020d72084d
12 changed files with 165 additions and 38 deletions

View File

@@ -306,6 +306,61 @@ error without reporting one, ConfigKit emits a generic `version.hook_failed`
diagnostic and suppresses the returned error text. Warnings alone are retained on a
successful result. Callback panics remain programming failures.
#### Shared source-version checks
`Options.SourceVersionMode` and `LayeredOptions.SourceVersionMode` select how
one `Definition.Version` policy applies across source documents. The zero value
`SourceVersionModeDefault` preserves the existing main-only check at its
effective path and existing protected-path behavior. `SourceVersionModeIfPresent`
checks each participating document that declares a version and permits absent
non-main declarations. `SourceVersionModeRequired` rejects a participating
document without a declaration. Enabled modes require a usable `VersionRule`
and checker; an unknown mode or unusable rule is an options error before source
access or callbacks.
In enabled modes, `Definition.Version.Path` is interpreted in each acquired
document's own coordinates, before placement and composition. The main document,
direct underlay documents, imported documents (including transitive and glob
matches), and the selected overlay participate. `NoSource`, absent optional
imports, empty underlay groups, defaults, resolution output, inheritance, and
synthetic CLI overrides are not documents to check. An absent declaration in an
actual main document still reaches the checker in if-present mode; required mode
rejects it first. With `NoSource`, the existing single absent-main checker
behavior remains in both enabled modes. If-present omissions in non-main
documents skip the checker. Explicit null is present and reaches the checker;
unsupported selected values produce `version.type`. No equality with the main
declaration or non-null rule is imposed. Acceptance establishes only that the
declaration is accepted by the consumer's checker; it does not establish that
each fragment conforms to a complete application schema. Final assembled
decoding and application validation still run once.
Accepted non-main declarations are consumed from their owned payload before
composition; their authored ancestors remain, even if empty. The main
declaration remains in the application. Ordinary release metadata should use a
different path. Enabled main protection uses the main input's effective path:
its `Destination` prefixed to the source-local `VersionRule.Path`. This protects
the remaining payload against imports, underlays, inheritance, and CLI
overrides. Thus a mounted main looks up a local header while ownership checks
protect its destination-prefixed application path. Main checker diagnostics and
declaration locations use source-local coordinates; ordinary payload
diagnostics continue to use effective paths. Default-mode diagnostics are
unchanged.
`SourceInfo.VersionCheck` is nil when enabled declaration processing did not
occur. Otherwise it records a source-local `Path`, the observed `Version` state
(`Present`, `Null`, and, when disclosed, exact `Text`), an actual or nearest
available `Location`, and whether text was redacted. A non-nil record with
`Present == false` records observed absence; it does not say the checker ran or
accepted a declaration. During callbacks and in failed-load source records,
text is conservatively withheld because final classification may not be
available. Successful final source records reflect completed sensitivity
classification at the declaration's mounted path and ancestors, including
historical classification. Redaction empties `Text` while retaining presence
and null state. Returned copies are detached; evidence does not reopen inputs.
Consult [ADR 0013](adr/0013-shared-source-version-checks.md) for the accepted
decision and the [source-version roadmap](roadmap/source-version-checks.md) for
its implementation record.
### Layered metadata
`Result.Metadata` describes every final canonical path. Queries retain explicit

View File

@@ -20,6 +20,7 @@ sanitized shapes using only ConfigKit and the Go standard library:
| Mounted collections | Entry-declared relative destinations, nested metadata/prompt/profile imports, local inheritance, and a version-only higher-tier override | Collection IDs, profile meaning, and opening/interpreting prompt resources |
| Named presets | One-load sibling inheritance, explicit false, nested destination resolution, and source/derivation inspection | Choosing and executing a preset |
| Effective configuration diff | Same-type frozen effective comparisons for two selected files or base-versus-overlay impact | Source/options selection and consumer-owned safe presentation |
| Shared source-version checks | One `Definition.Version` policy for accepted declarations across participating source documents, with optional or required declarations and sanitized evidence | Choosing which declarations the application accepts; final assembled schema and domain validation |
The YAML under [`testdata`](../../examples/consumers/testdata) is loaded by the
executable examples and ordinary tests. It contains no private application data,
@@ -53,6 +54,18 @@ both without redefining their syntax. ConfigKit overlays are configuration overl
they do not select or replace an application's LLM, model, pipeline, report, or
execution profile concepts.
## Shared source-version checks
[`LoadVersionedService`](../../examples/consumers/source_version.go) demonstrates
if-present and required modes with one `Definition.Version` rule across a mounted
main input and an underlay. The example reads only sanitized
`SourceInfo.VersionCheck` fields; its executable test is in
[`layered_test.go`](../../examples/consumers/layered_test.go). The
[configuration contract](../config.md#shared-source-version-checks) defines
participation, source-local lookup and diagnostics, non-main header consumption,
main-path protection, default behavior, and evidence disclosure. Accepted
declarations do not replace final assembled decoding or application validation.
## Effective configuration diffs
[`CompareFiles`](../../examples/consumers/diff.go) loads two caller-selected files

View File

@@ -40,6 +40,7 @@ public behavior.
| --- | --- |
| Repository orientation or component responsibility | [Component overview](internal/overview.md) |
| Input destinations | [Configuration contract](config.md#input-destinations), [ADR 0011](adr/0011-input-destinations.md), and the destination tests below |
| Shared source-version checks | [Configuration contract](config.md#shared-source-version-checks), [ADR 0013](adr/0013-shared-source-version-checks.md), and the version/source-version tests below |
| Documentation changes | The owning document |
| Licensing, dependencies, attribution, or release-document changes | [Project grant](../COPYRIGHT) and [attribution](oss/attribution.md); release changes also follow the release procedure |
| Architecture decisions or future work | [Deferred scope](roadmap/deferred.md) and relevant ADRs listed below |
@@ -168,6 +169,7 @@ code changes. Use the component overview to find the corresponding implementatio
| Sibling inheritance, provenance, history, sensitivity | [Expansion](../internal/engine/inheritance_test.go), [destination scopes](../internal/engine/inheritance_walk_test.go), [origins](../internal/engine/inheritance_origin_test.go), [history](../internal/engine/inheritance_history_test.go), [secrets](../internal/engine/inheritance_secret_test.go), [public loading](../facade_inheritance_test.go) | `go test ./internal/engine -run 'Inheritance\|Inherited'` and `go test . -run '^TestFacadeInheritance\|^TestFacadeInheritedSecrets'` |
| Layered loading and source equivalence | [Grouped lifecycle](../internal/engine/load_request_test.go), [layered facade](../facade_layered_test.go), [equivalence](../facade_equivalence_test.go) | `go test ./internal/engine -run '^TestGrouped'`, `go test . -run '^TestFacadeLayered'`, and `go test . -run '^TestEquivalentSourceForms'` |
| Input and relative-import destinations, mounted sources, and source ownership | [Destination engine tests](../internal/engine/destination_test.go), [tier tests](../internal/engine/destination_tiers_test.go), [import traversal and version tests](../internal/engine/destination_import_test.go), [accounting tests](../internal/engine/destination_accounting_test.go), [lifecycle inspection tests](../internal/engine/destination_import_lifecycle_test.go), [public source/error tests](../facade_destination_test.go), [resource contexts](../facade_resource_context_test.go), and [consumer examples](../examples/consumers/destinations_test.go) | `go test ./internal/engine -run 'Destination|Import|Glob|Mounted'`, `go test . -run 'Destination|Import|SourceContext|FacadeMounted'`, and `go test ./examples/consumers` |
| Shared source-version modes and evidence | [Engine source-version tests](../internal/engine/source_version_test.go), [public facade tests](../facade_source_version_mode_test.go), and [consumer example tests](../examples/consumers/layered_test.go) | `go test ./internal/engine -run 'SourceVersion'`, `go test . -run 'SourceVersion'`, and `go test ./examples/consumers` |
| Schema, defaults, projection, cloning | [Schema](../internal/engine/schema_test.go), [decoding](../internal/engine/decode_test.go), [projection](../internal/engine/projection_test.go) | `go test ./internal/engine -run 'Schema\|Decode\|Projection\|Clone\|Inline\|CompareDocument'` |
| Lifecycle, resolution, validation, callback ownership | [Loading](../internal/engine/load_test.go), [resolution](../internal/engine/resolution_test.go), [validation](../internal/engine/validation_test.go), [ownership](../internal/engine/callback_ownership_test.go), [independence](../internal/engine/independence_test.go) | `go test ./internal/engine -run 'Load\|Resolution\|Validation\|Validator\|Hook\|Callback\|Parallel'` |
| Paths, metadata, provenance | [Paths](../internal/engine/path_test.go), [metadata](../internal/engine/metadata_test.go), [provenance](../internal/engine/provenance_test.go) | `go test ./internal/engine -run 'Path\|Metadata\|Provenance\|Queries'` |

View File

@@ -10,7 +10,8 @@ Implemented component owners:
- `internal/engine` owns host and native-filesystem source acquisition,
grouped strict composition, recursive precedence assembly, per-input mapping
placement and immediate-parent-relative import placement within that
assembly, and destination-local sibling inheritance before typed decoding.
assembly, destination-local sibling inheritance before typed decoding, and
shared source-version checking with sanitized declaration evidence.
It retains each source's effective placement alongside physical source
identity and owns schema
inspection, lifecycle coordination, callback auditing,
@@ -44,7 +45,8 @@ these constraints and rejects exported aliases, fields, or signatures involving
internal types.
The [configuration contract](../config.md) owns implemented YAML and lifecycle
semantics, including [input destinations](../config.md#input-destinations) and
semantics, including [input destinations](../config.md#input-destinations),
[shared source-version checks](../config.md#shared-source-version-checks), and
[effective configuration diffs](../config.md#effective-configuration-diffs).
The [consumer adoption guide](../consumers/README.md) owns application guidance.
The [architecture policy](../policy/architecture.md) owns contributor
@@ -55,4 +57,5 @@ decision. See the [development guide](../development.md) for validation commands
and [release procedure](../release.md) for source-candidate gates. [ADR
0009](../adr/0009-sibling-inheritance.md) records why inheritance is a built-in
post-assembly structural operation. [ADR 0012](../adr/0012-relative-import-destinations.md)
records the relative-import extension.
records the relative-import extension; [ADR 0013](../adr/0013-shared-source-version-checks.md)
records the source-version decision.

View File

@@ -1,6 +1,6 @@
# Implement shared source version checks
Status: Stages 1–13 complete; documentation reconciliation remains.
Status: complete. All 14 implementation stages are validated.
Audience: a Luna coding agent implementing one numbered stage per prompt, in
order. The [feature roadmap](source-version-checks.md) owns target behavior and
@@ -668,3 +668,27 @@ No environmental limitation affected validation; checks ran on Linux/amd64.
Done: implementation, coverage, documentation, and approved scope agree. No
product questions remain open under the roadmap and concrete decisions above.
Completion evidence: updated the public Go comments, configuration contract,
consumer guidance, development guide, and component ownership summary for the
implemented behavior. Reconciled the original source-version request with later
accepted decisions, marked the source-version roadmap implemented, and repaired
relative-import/remediation references to the overwritten plan using the
confirmed `d9f08ff:docs/roadmap/implementation.md` history pointer. The scope
audit found no default-mode expansion, equality/non-null rule, extra path
restriction, fragment decoding, callback-order promise, new uniqueness/cap,
unsafe evidence query, or release gate. Reviewed behavioral coverage in
`internal/engine/source_version_test.go`,
`facade_source_version_mode_test.go`,
`internal/engine/secret_classification_test.go`,
`internal/engine/inheritance_secret_test.go`, and
`examples/consumers/layered_test.go`. These checks passed with Go
`go1.26.8 linux/amd64`:
- `GOTOOLCHAIN=local ./scripts/check.sh`
- `GOTOOLCHAIN=local GOPROXY=off go test . -run '^TestLocalDocumentationLinks$' -count=1`
- `git diff --check`
No runtime code changed in this documentation unit, so the race suite was not
rerun. No environmental limitation affected validation; checks ran on
Linux/amd64 only. Publication and release preparation remain outside this work.

View File

@@ -284,6 +284,12 @@ new limit values or their accounting machinery.
## Partially Accepted Addition: Shared Source Specification Checks
Status: the shared-policy portion below is implemented. Current behavior is
defined by the [configuration contract](../config.md#shared-source-version-checks),
and the accepted decision and implementation evidence are in
[ADR 0013](../adr/0013-shared-source-version-checks.md) and the
[source-version roadmap](source-version-checks.md).
### Accepted Scope
A ConfigKit consumer defines one configuration specification, which may evolve
@@ -322,16 +328,19 @@ separate from `Definition.Version`, with ordinary imports exempt from independen
checks. It also recommended consuming accepted entry headers and exposing them
as source evidence while leaving imported release metadata untouched.
That full set of semantics has not been accepted. The accepted direction uses
one shared `Definition.Version` policy and optional or required declarations
across participating sources. Separately versioned subsets or collections are
outside this addition's scope and may be considered independently in the future.
Header consumption and inspection from the original proposal remain design
suggestions, not accepted requirements.
The independent collection-entry policies and exemption for ordinary imports
were not accepted. The accepted direction instead uses one shared
`Definition.Version` policy and optional or required declarations across
participating sources. Separately versioned subsets or collections remain
outside this addition's scope. Header consumption and sanitized source evidence,
which were suggestions in the original proposal, were subsequently accepted for
this shared-policy design and are implemented as described by the linked
contract.
### Remaining Design Work
### Design Questions Resolved by the Accepted Roadmap
The following details remain to be resolved before implementation:
The following questions were open in the original request and are resolved by
the accepted roadmap and ADR 0013:
- How the configured declaration path is interpreted for individual sources,
particularly before destination placement.
@@ -345,10 +354,11 @@ The following details remain to be resolved before implementation:
existing string/decimal-integer version vocabulary.
- The opt-in API, callback lifecycle, and source-local diagnostic attribution.
In particular, the original example of an imported `version: "2.4.0"` release
label is not guaranteed to remain outside checking in an enabled mode. That
depends on the chosen header lookup semantics. No automatic field consumption,
new coercion, or per-collection checker should be inferred from partial acceptance.
In particular, an imported `version: "2.4.0"` at the configured source-local
header path is checked and consumed in an enabled mode. Consumers that need an
ordinary release label retain it at a different path. No automatic field
consumption applies in the default mode, and no new coercion or per-collection
checker is part of the implemented design.
## Requested Addition: Relative Import Destinations

View File

@@ -1,12 +1,12 @@
# Relative Import Destinations Roadmap
Status: complete. The
[implementation plan](implementation.md) preserves sequencing, behavior
evidence, and the final compatibility audit.
Status: complete. The implementation plan and its evidence were replaced by the
shared source-version plan and remain in Git history at
`d9f08ff:docs/roadmap/implementation.md`.
This roadmap addresses only the relative-import-destination addition in
the [PromptKit request](promptkit-feature-request.md#requested-addition-relative-import-destinations).
Independent source specification headers are deferred for reconsideration after
this work is implemented; they are not a prerequisite or part of this feature.
Source-version checks were outside this roadmap's scope and are now implemented
separately in the [shared source-version roadmap](source-version-checks.md).
## Targeted end state

View File

@@ -2,7 +2,7 @@
Reviewed `d3d468a..945e111` against the approved
[input-destinations roadmap](input-destinations.md),
input-destination implementation plan (preserved at
input-destination implementation plan (preserved in Git history at
`315f464:docs/roadmap/implementation.md`), and
[ADR 0011](../adr/0011-input-destinations.md).
@@ -93,7 +93,8 @@ Required remediation:
Reviewed `7248a8b..10edd95` against the
[relative-import roadmap](relative-import-destinations.md), completed
[implementation plan](implementation.md), and
implementation plan (preserved in Git history at
`d9f08ff:docs/roadmap/implementation.md`), and
[ADR 0012](../adr/0012-relative-import-destinations.md).
The implementation matches the selected architecture: literal string segments

View File

@@ -1,9 +1,10 @@
# Shared Source Version Checks Roadmap
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
Status: implemented and validated. Current behavior is owned by the
[configuration contract](../config.md#shared-source-version-checks), and the
accepted decision is recorded in [ADR 0013](../adr/0013-shared-source-version-checks.md).
The completed [implementation plan](implementation.md) records execution and
validation evidence. This roadmap develops the
partially accepted source-version request in
[PromptKit's proposal](promptkit-feature-request.md#partially-accepted-addition-shared-source-specification-checks)
using the consumer's single `Definition.Version` policy. The design direction
@@ -19,8 +20,10 @@ is one consumer-owned configuration specification and one acceptance policy.
Different accepted declarations may coexist: ConfigKit does not require exact
equality with the main declaration, impose SemVer, or invent an expected value.
The consumer selects a load-wide enum on ordinary and layered options. Its zero
value retains current behavior; the implementation plan selects exported names.
The consumer selects `SourceVersionMode` on ordinary and layered options. Its
zero value retains current behavior. The modes are
`SourceVersionModeDefault`, `SourceVersionModeIfPresent`, and
`SourceVersionModeRequired`.
The same `Definition.Version` can be reused across loads with different
strictness. The three modes are:
@@ -204,8 +207,9 @@ outside this feature's completion criteria.
The maintainer has accepted all three decisions below. Together with the mode
API location, source participation, main-path handling, source-record evidence,
and nested mapping ancestor preservation above, these settle the discussed
product decisions. The [implementation plan](implementation.md) selects public
names and integration mechanics; the feature is not yet implemented.
product decisions. Public names and integration mechanics are recorded in the
completed [implementation plan](implementation.md); current behavior belongs
to the [configuration contract](../config.md#shared-source-version-checks).
### Sensitivity of consumed declaration evidence

View File

@@ -25,7 +25,9 @@ type Underlay struct{ Inputs []Input }
// ignores it. Overrides remain explicit CLI records, not general mappings.
// SourceVersionMode applies one declaration policy to main, underlay, import,
// and selected overlay documents. Enabled modes interpret the version path
// source-locally while protecting main's destination-prefixed path.
// source-locally, consume accepted non-main declarations, and protect main's
// destination-prefixed path. The zero value preserves existing behavior; see
// the shared source-version contract in docs/config.md.
type LayeredOptions[T any] struct {
Definition Definition[T]
SourceVersionMode SourceVersionMode

View File

@@ -18,7 +18,10 @@ type Definition[T any] struct {
}
// SourceVersionMode controls schema-version declarations across one complete
// load. The zero value preserves the existing effective-path version check.
// load. The zero value preserves the existing main-only effective-path check
// and its protected-path behavior. Enabled modes check participating documents
// at source-local Definition.Version.Path coordinates and consume accepted
// non-main declarations. See the shared source-version contract in docs/config.md.
type SourceVersionMode uint8
const (
@@ -77,7 +80,10 @@ type Override struct {
type Resolution struct{ value *engine.Resolution }
// VersionRule declares the input path and application checker for a schema version.
// At that path, string and decimal-integer input is supplied as Version.Text.
// Default source-version mode interprets Path as the existing effective path;
// enabled modes interpret it in each participating document's local coordinates.
// At the selected path, strings and strict decimal integers supply their exact
// spelling as Version.Text. See docs/config.md for the complete contract.
type VersionRule struct {
Path Path
Check func(Version, *Validation) error

View File

@@ -197,14 +197,21 @@ type SourceInfo struct {
Kind SourceKind
UnderlayIndex int
ImportedFrom *Location
// VersionCheck is the sanitized source-local version declaration observed
// during an enabled source-version load. It is nil otherwise.
// VersionCheck is sanitized evidence for source-local declaration processing
// in an enabled source-version load. It is nil when that processing did not
// occur, including default mode and synthetic CLI sources. During callbacks
// and failed loads, text is conservatively withheld; successful final source
// records reflect completed sensitivity classification.
VersionCheck *SourceVersionCheck
}
// SourceVersionCheck describes a source-local version declaration observed
// during an enabled load. Text is empty when classification or conservative
// early-access redaction withholds it; Present and Null retain their meaning.
// during an enabled load. A non-nil record with Present false records observed
// absence, but does not imply that a checker ran or accepted a value. Text is
// empty when sensitivity classification or conservative callback-time/failed-
// load redaction withholds it; Present and Null retain their meaning. Copies
// returned by source queries are detached. See docs/config.md for disclosure
// and lifecycle details.
type SourceVersionCheck struct {
Path Path
Version Version