Update ConfigKit adoption plan for version 0.3.0

This commit is contained in:
2026-09-13 15:49:26 +00:00
parent 00972e8d48
commit c403a38b50
2 changed files with 168 additions and 139 deletions

View File

@@ -7,27 +7,26 @@ default application, and configuration-inspection machinery with ConfigKit,
while preserving Notarius ownership of pipeline semantics, module catalogs, while preserving Notarius ownership of pipeline semantics, module catalogs,
runtime resolution, and invocation behavior. runtime resolution, and invocation behavior.
This roadmap is based on ConfigKit v0.2.0, the current stable release in the This roadmap targets ConfigKit v0.3.0. Its released source-origin APIs support
local `../ConfigKit` checkout. ConfigKit's maintained consumer guide includes a source-aware normalization within one load, removing the prior upstream
Notarius-shaped example, and its complete test suite passes locally. The dependency gate. Ordered implementation work belongs in
dependency starts at v0.2.0; completing source-aware normalization requires a
reviewed release with the extension below. Do not follow an unreviewed branch
tip. Ordered implementation work belongs in
[the implementation plan](implementation.md). [the implementation plan](implementation.md).
### Source Metadata Dependency ### Released Source Metadata Support
Review for implementation identified an API gap in v0.2.0: `Resolution` Use `Resolution.InputInfo(path) (FieldInfo, bool)` to query the fixed decoded
exposes input presence and change recording, but not declaration origins or entry state, and `Resolution.Source(id) (SourceInfo, bool)` to retrieve an
source paths. Those are available only on the completed `Result`, whose already-acquired source's canonical file path. These callback-scoped queries
effective and explanation snapshots are already frozen. The target of return detached records and preserve original input attribution despite
recording declaration-relative path normalization in those snapshots therefore consumer normalization or map-key moves. Notarius records resolved values
requires an upstream extension. The selected approach is to request source through the existing normalization API before ConfigKit freezes inspection
origins and canonical source records during resolution, then adopt a reviewed output; no post-load path conversion or second load is needed.
release providing that API. The implementation plan records the dependency
gate. Resolving paths only after loading with a separate inspection report was The v0.3.0 public-facade refactor preserves consumer signatures and introduces
considered but not selected; the agreed effective/explanation contract remains no additional migration. Use only the root public package. Go 1.25 remains
the target. ConfigKit v0.2.0 alone is insufficient for that part of the target. supported; the private YAML v4 prerelease dependency is unchanged. ConfigKit's
macOS support is now best-effort, consistent with Notarius's platform policy.
No application platform expansion or new release gate is required.
## Motivation ## Motivation
@@ -119,7 +118,7 @@ requirements defined by the architecture and current integration contracts.
- the meaning and validation of every Notarius field; - the meaning and validation of every Notarius field;
- pipeline, module, validator, artifact, and reference catalogs; - pipeline, module, validator, artifact, and reference catalogs;
- conversion from configuration-facing values to runtime pipeline types; - conversion from configuration-facing values to runtime pipeline types;
- source-relative interpretation of configured external reference paths; - source-relative interpretation of configured filesystem paths;
- run-time selectors and actions such as lane selection, input, resume, - run-time selectors and actions such as lane selection, input, resume,
recomputation, session identity, and CLI reference changes; recomputation, session identity, and CLI reference changes;
- PromptKit profile discovery and validation; and - PromptKit profile discovery and validation; and
@@ -142,7 +141,7 @@ Use the following root declaration:
version: 5 version: 5
``` ```
ConfigKit v0.2.0 accepts string or strict decimal-integer input at the exact ConfigKit v0.3.0 accepts string or strict decimal-integer input at the exact
path selected by its `VersionRule`. It passes the original spelling to the path selected by its `VersionRule`. It passes the original spelling to the
application checker and can decode an accepted integer into a string-backed Go application checker and can decode an accepted integer into a string-backed Go
field. This narrow exception lets Notarius retain its existing numeric YAML field. This narrow exception lets Notarius retain its existing numeric YAML
@@ -295,20 +294,38 @@ to Notarius input, reference, output, cache, debug, or PromptKit profile paths.
### Paths And Source Ownership ### Paths And Source Ownership
Resolve relative external reference paths and `promptkit.profile_file` and Resolve every nonempty relative application filesystem path authored in
`promptkit.profile_dir` relative to the file that supplied the surviving value. configuration against the canonical directory of the file supplying the
This deliberately changes PromptKit profile-source paths from their current surviving value. This includes external references, `promptkit.profile_file`,
working-directory convention in version 5. Absolute paths remain absolute. `promptkit.profile_dir`, and output, cache, and debug directories. Absolute
Keep output, cache, and debug relative-directory semantics unchanged; they are paths remain unchanged. This deliberately changes configured PromptKit sources
runtime destinations rather than files bundled with configuration fragments. and runtime destinations from working-directory-relative behavior in version 5.
Use ConfigKit's source metadata to identify each surviving declaration's File-authored profile replacements use the profile file's directory, including
origin, including profile replacements and values inherited from the base. equal-valued replacements. Inherited values keep their base-file origin.
Record path normalization so effective output and explanation reflect the Built-in relative defaults have no declaring file and use the canonical main
paths used at runtime. Preserve attribution when identifier normalization configuration directory. Explicit CLI-relative paths use the invocation's
renames an enclosing map key. Do not resolve overwritten or removed path working directory, including output/debug overrides submitted through ConfigKit.
values or infer source ownership from diagnostic display labels. Explicit CLI CLI references remain invocation-owned. Empty optional cache paths keep their
paths retain their working-directory interpretation. existing disabled/automatic meaning; do not turn an empty path into a directory.
Use `InputInfo` at original scalar paths and `Source` for their source IDs,
not composite parent origins or diagnostic display labels. Preserve original
path mappings when identifiers are normalized. Record normalization so runtime,
effective output, and explanation agree; do not resolve overwritten values.
Canonical target-file directories, not symlink alias directories, supply bases.
Notarius's file-backed loader must supply the canonical main directory and the
invocation directory where needed. If a nonempty relative value unexpectedly
lacks the provenance needed to choose its base, report a safe field diagnostic
and fail loading rather than silently choose a different directory. This is a
correctness failure, not an added restriction on operators' valid paths. Do not
copy the upstream example's optional warning-and-leave-relative fallback.
Application paths may be absolute or contain `../`; do not add confinement,
target-existence checks, or new symlink restrictions during normalization.
ConfigKit's own import and profile-source rules remain unchanged. Module-owned
dynamic options are not automatically interpreted as filesystem paths.
## Discovery, Precedence, And Overrides ## Discovery, Precedence, And Overrides
@@ -422,8 +439,8 @@ configuration or a new durable JSON API. There is no unredacted mode.
The implementation must address the following coherent work areas: The implementation must address the following coherent work areas:
- add and pin a reviewed `gitea.maximumdirect.net/eric/ConfigKit` release with - pin `gitea.maximumdirect.net/eric/ConfigKit v0.3.0` and use its public
v0.2.0's semantics and the required source-origin API; source-origin APIs;
- introduce the version 5 typed document and its ConfigKit definition; - introduce the version 5 typed document and its ConfigKit definition;
- replace `LoadFileConfig`, custom `UnmarshalYAML` implementations, manual - replace `LoadFileConfig`, custom `UnmarshalYAML` implementations, manual
strict-parser checks, presence flags, `ApplyFileConfig`, and redundant strict-parser checks, presence flags, `ApplyFileConfig`, and redundant
@@ -434,7 +451,7 @@ The implementation must address the following coherent work areas:
discovery; discovery;
- enable ConfigKit imports and configuration profiles, wire `--config-profile` - enable ConfigKit imports and configuration profiles, wire `--config-profile`
through all configuration-loading commands, and retain declaration origins through all configuration-loading commands, and retain declaration origins
for relative file paths; for configured filesystem paths;
- retire field-level environment overlays while retaining `NOTARIUS_CONFIG`; - retire field-level environment overlays while retaining `NOTARIUS_CONFIG`;
- classify current run flags so only true configuration overrides use - classify current run flags so only true configuration overrides use
ConfigKit override records and invocation-only state remains outside the ConfigKit override records and invocation-only state remains outside the
@@ -458,8 +475,10 @@ migration section with a concise version 4-to-5 migration guide covering:
- expanding scalar module bindings into `{module: ...}` objects; - expanding scalar module bindings into `{module: ...}` objects;
- expanding scalar external references into `{path: ...}` objects; - expanding scalar external references into `{path: ...}` objects;
- moving lane-level reference aliases to `extract.references`; - moving lane-level reference aliases to `extract.references`;
- resolving configured PromptKit profile-source paths from their declaring - resolving configured PromptKit profile-source and output/cache/debug paths
file instead of the working directory; from their declaring file instead of the working directory, and built-in
relative defaults from the main configuration directory; CLI-relative paths
retain their invocation-directory base;
- using imports for whole pipeline definitions and configuration profiles for - using imports for whole pipeline definitions and configuration profiles for
overlays, including complete replacement of step sequences; overlays, including complete replacement of step sequences;
- replacing retired operational environment overrides with YAML or supported - replacing retired operational environment overrides with YAML or supported
@@ -517,9 +536,10 @@ Required Notarius coverage includes:
and profile precedence through the real ConfigKit loader; and profile precedence through the real ConfigKit loader;
- profile sequence replacement and explicit clearing, so Notarius does not - profile sequence replacement and explicit clearing, so Notarius does not
accidentally append or merge ordered steps; accidentally append or merge ordered steps;
- relative reference and PromptKit profile-source paths from root files, - relative references, PromptKit sources, and destination paths from root files,
imported fragments, and overlays, including an unchanged inherited value, imported fragments, and overlays, including inherited and equal-valued replaced
a replaced value, and an enclosing normalized identifier; values, normalized enclosing identifiers, default bases, CLI bases, and empty
optional cache settings;
- matching configuration-profile selection across execution, validation, - matching configuration-profile selection across execution, validation,
pipeline listing, effective output, and explanation, without provider calls; pipeline listing, effective output, and explanation, without provider calls;
- checked dynamic integer conversion at each production module option boundary; - checked dynamic integer conversion at each production module option boundary;
@@ -572,9 +592,8 @@ profile validation, as documented today; no live provider call is required.
## Acceptance Criteria ## Acceptance Criteria
- All configuration-loading commands use a pinned ConfigKit release providing - All configuration-loading commands use ConfigKit v0.3.0 through its public
the required source-origin API, building on v0.2.0, and no production code package, and no production code directly imports a YAML parser.
directly imports a YAML parser.
- Version 5 is the only accepted file contract, documents `version: 5` as its - Version 5 is the only accepted file contract, documents `version: 5` as its
canonical spelling, and has one canonical object representation for module canonical spelling, and has one canonical object representation for module
bindings and references. bindings and references.
@@ -592,9 +611,9 @@ profile validation, as documented today; no live provider call is required.
- Imports compose whole pipeline definitions and selected configuration - Imports compose whole pipeline definitions and selected configuration
profiles apply ConfigKit's documented overlay semantics consistently across profiles apply ConfigKit's documented overlay semantics consistently across
all configuration-loading commands. all configuration-loading commands.
- Relative external references and PromptKit profile-source paths use the - Configured relative filesystem paths use the surviving declaration's canonical
surviving declaration's source directory, and safe inspection agrees with directory; built-in defaults use the main configuration directory and CLI
the paths used at runtime. values use the invocation directory. Safe inspection agrees with runtime.
- The resolved pipeline remains detached, reference content remains excluded - The resolved pipeline remains detached, reference content remains excluded
from ordinary summaries, and its identity changes under the same semantic from ordinary summaries, and its identity changes under the same semantic
conditions as before. conditions as before.

View File

@@ -16,12 +16,10 @@ preserve the requested flexibility, and do not add application restrictions
under the guise of this migration. Tests protect behavior, not exact helper under the guise of this migration. Tests protect behavior, not exact helper
structure, incidental formatting, or a duplicated implementation of ConfigKit. structure, incidental formatting, or a duplicated implementation of ConfigKit.
The selected approach requires an upstream extension: ConfigKit v0.2.0 cannot ConfigKit v0.3.0 supplies the required source-origin APIs. Pin that release from
expose source origins during its resolution callback. See **Upstream Stage 1; there is no remaining upstream gate. Stage 7 uses the released
Prerequisite**. Stages 1–6 are independent of that missing capability. Stage 7 `Resolution.InputInfo` and `Resolution.Source` methods. Keep the fourteen
and all later stages have an explicit gate; the sprint is not ready for stages ordered and bounded as below.
unattended execution through that gate until the upstream release is available.
Do not mark a gated stage complete by weakening the feature contract.
Temporary coexistence of the old production loader and the new loader during Temporary coexistence of the old production loader and the new loader during
these stages is implementation scaffolding only. There is no supported dual these stages is implementation scaffolding only. There is no supported dual
@@ -32,7 +30,8 @@ final stage establishes repository-wide readiness.
## Repository Baseline ## Repository Baseline
Planning examined Notarius at `946fa10` plus the outstanding policy and roadmap Planning examined Notarius at `946fa10` plus the outstanding policy and roadmap
changes. The sibling ConfigKit checkout is tagged `v0.2.0`. changes. The dependency review now uses the sibling ConfigKit checkout tagged
`v0.3.0`, including its release guide and source-aware consumer example.
Relevant current owners are: Relevant current owners are:
@@ -47,7 +46,7 @@ Relevant current owners are:
| Debug configuration and resolved-pipeline output | `internal/core/config/redaction.go`, `internal/core/debugbundle/summary.go`, and the CLI debug handoff | | Debug configuration and resolved-pipeline output | `internal/core/config/redaction.go`, `internal/core/debugbundle/summary.go`, and the CLI debug handoff |
| Maintained examples | `examples/dnd-minimal.config.yml`, `examples/dnd-complete.config.yml`, `examples/profiles/dnd-extraction.yml`, and CLI production contract tests | | Maintained examples | `examples/dnd-minimal.config.yml`, `examples/dnd-complete.config.yml`, `examples/profiles/dnd-extraction.yml`, and CLI production contract tests |
| Direct YAML test dependency | `internal/cli/production_contract_test.go` also parses embedded prompt definitions using `yaml.v3` | | Direct YAML test dependency | `internal/cli/production_contract_test.go` also parses embedded prompt definitions using `yaml.v3` |
| Upstream contract | ConfigKit `docs/config.md`, `docs/consumers/README.md`, `load.go`, `resolution.go`, `metadata.go`, `records.go`, `path.go`, and consumer examples at v0.2.0 | | Upstream contract | ConfigKit `docs/config.md`, `docs/consumers/README.md`, public `load.go`, `lifecycle.go`, `metadata.go`, `records.go`, `path.go`, and consumer examples at v0.3.0 |
The sibling checkout is reference material, not a production dependency path. The sibling checkout is reference material, not a production dependency path.
Do not commit a local `replace`, modify upstream, or invent a future API as part Do not commit a local `replace`, modify upstream, or invent a future API as part
@@ -57,9 +56,8 @@ of these Notarius stages.
### Configuration And Dependency Boundary ### Configuration And Dependency Boundary
- Initially pin `gitea.maximumdirect.net/eric/ConfigKit v0.2.0`. Stage 7 may - Pin `gitea.maximumdirect.net/eric/ConfigKit v0.3.0`. Use the root public
require a reviewed release providing the agreed upstream extension. A later package, never its private engine or an unreviewed `main` revision.
pin must be explicit, never an unreviewed `main` revision.
- Use a string-backed document version and a `/version` rule accepting exactly - Use a string-backed document version and a `/version` rule accepting exactly
text `5`; both numeric `version: 5` and quoted `version: "5"` are accepted. text `5`; both numeric `version: 5` and quoted `version: "5"` are accepted.
Maintained examples use the numeric form. Reject missing/null/unsupported Maintained examples use the numeric form. Reject missing/null/unsupported
@@ -135,14 +133,18 @@ rules; empty and exact `default` select no overlay. Do not invent stricter name
validation or whitespace normalization than the upstream profile contract. validation or whitespace normalization than the upstream profile contract.
Enable imports without a separate Notarius enablement flag. The canonical Enable imports without a separate Notarius enablement flag. The canonical
selected file's directory is the configuration root. Relative file references selected file's directory is the configuration root. Every nonempty configured
and PromptKit profile sources use the surviving declaration's directory; relative filesystem path (external references, PromptKit profile sources, and
absolute values remain absolute. Resolve these to absolute paths before output/cache/debug directories) uses the surviving declaration's canonical
runtime conversion, without reading the referenced contents. Output/cache/debug directory. Built-in relative defaults use the main configuration directory;
relative directories retain working-directory semantics. CLI reference paths explicit CLI values use the invocation directory. Absolute values remain
retain the existing working-directory semantics and generated-reference unchanged. Empty optional cache paths retain their existing meaning.
Resolve paths before runtime conversion without reading target contents.
CLI references retain their existing runtime handling and generated-reference
protection. Configuration-root confinement applies only to ConfigKit's imported protection. Configuration-root confinement applies only to ConfigKit's imported
configuration and overlay files. configuration and overlay files, not application paths. Do not infer path
semantics for arbitrary dynamic module options.
## Stage 1 — Add ConfigKit And The Version 5 Document Types ## Stage 1 — Add ConfigKit And The Version 5 Document Types
@@ -150,7 +152,7 @@ configuration and overlay files.
**Work:** **Work:**
1. Pin v0.2.0 in `go.mod`/`go.sum` and inspect its actual exported API. 1. Pin v0.3.0 in `go.mod`/`go.sum` and inspect its actual exported API.
2. Add `document.go` and `load.go` in `internal/core/config` (or equivalent 2. Add `document.go` and `load.go` in `internal/core/config` (or equivalent
cohesive files) with the complete plain document types, finite validator cohesive files) with the complete plain document types, finite validator
type, explicit reference union, and YAML-tagged validation-policy fields. type, explicit reference union, and YAML-tagged validation-policy fields.
@@ -163,7 +165,8 @@ configuration and overlay files.
scaffolding; do not advertise partially implemented v5 support. scaffolding; do not advertise partially implemented v5 support.
5. Add the next available ADR (expected `0018-adopt-configkit.md`) recording 5. Add the next available ADR (expected `0018-adopt-configkit.md`) recording
the accepted ownership, v5 break, imports/profiles, and environment policy. the accepted ownership, v5 break, imports/profiles, and environment policy.
Record the source-origin dependency without claiming it is implemented. Record application path-base policy and the released source-origin APIs;
do not claim the Notarius migration is implemented merely because upstream is.
**Acceptance:** v5 numeric/quoted versions decode; unsupported versions fail **Acceptance:** v5 numeric/quoted versions decode; unsupported versions fail
before document decoding; representative canonical bindings and references before document decoding; representative canonical bindings and references
@@ -191,7 +194,8 @@ small; generic YAML exhaustiveness remains upstream.
and required fields in a present local-backend object. Preserve mutually and required fields in a present local-backend object. Preserve mutually
exclusive profile sources and the existing endpoint/range constraints. exclusive profile sources and the existing endpoint/range constraints.
4. Keep filesystem checks and PromptKit profile catalog lookup out of callbacks. 4. Keep filesystem checks and PromptKit profile catalog lookup out of callbacks.
This stage trims profile-source paths but does not yet resolve their bases. This stage trims filesystem paths but does not yet resolve their bases;
Stage 7 owns all source-aware path normalization.
5. Extract small reusable value checks where needed so runtime validation and 5. Extract small reusable value checks where needed so runtime validation and
document validation do not separately implement the same rule. Collect document validation do not separately implement the same rule. Collect
independent errors through ConfigKit with safe messages and field paths. independent errors through ConfigKit with safe messages and field paths.
@@ -343,46 +347,58 @@ Test rendering failure and caller mutation at these real local boundaries.
**Goal:** Normalize file paths using their effective source origins and retain **Goal:** Normalize file paths using their effective source origins and retain
correct ConfigKit inspection history. correct ConfigKit inspection history.
**Prerequisite gate:** A reviewed ConfigKit release must expose surviving input origin and canonical **Work:**
source information during resolution. Confirm the actual API and pin that
release before implementing this stage. If only v0.2.0 is available, stop here
and report the unmet dependency. Do not implement an upstream fork, reload the
configuration twice, parse YAML independently, or silently change the promised
effective output.
**Work after the gate:** 1. Query `resolution.InputInfo(originalPath)` for each path-bearing scalar.
It returns `(FieldInfo, bool)` from fixed entry-state metadata, unaffected by
1. Resolve path origins at original input paths before map-key normalization earlier normalization, additions, removals, or moves. Use Stage 3's original
and before recording changes can replace a source origin. Use the scalar path mapping for renamed keys. Read `Origin.Layer` and the exact scalar's
origin and source ID to get the canonical declaring file; do not pick the `Origin.Locations`; use `resolution.Source(location.SourceID)` to obtain
first origin of a composite parent mapping. `(SourceInfo, bool)` and its canonical `Path`. Do not select an arbitrary
2. Join nonempty relative external reference paths and PromptKit profile-source origin of a composite parent.
paths to that file's directory. Preserve absolute values. Do not read or 2. Implement one narrow application path-base helper shared by typed traversals.
require existence of referenced files in this callback. Base/profile file values use the declaring file directory; default relative
3. Record normalized paths and map moves so the frozen effective view matches values use the canonical main directory; CLI relative values use the
runtime values and explanation can trace back to the original declaration. invocation directory supplied by the CLI load boundary. Capture that
Keep map collision checks ahead of mutation; process stable sorted keys. directory once for the load. Obtain canonical main-file identity consistently
4. Leave destination directories unchanged except existing whitespace with ConfigKit's acquired source records; no second parse or load.
normalization. CLI reference paths remain runtime-owned. No configuration 3. Normalize nonempty relative external references, PromptKit profile sources,
root confinement or symlink policy is added to referenced application files. and output/cache/debug directories to absolute paths. Preserve already
5. Enable imports and selected profiles on the public new loader, using absolute values after existing whitespace handling. Empty optional cache
`File` and the selected file's canonical directory as the root. Use paths retain their automatic/disabled semantics. Do not inspect target
ConfigKit's composition and profile behavior directly. existence or read referenced content.
4. Record normalized paths and map moves so frozen inspection matches runtime
and traces the original declaration. Keep collision checks ahead of mutation
and process stable sorted keys. Use retained input metadata only as provenance,
not as a substitute for reading the current working value.
5. Fail with a safe field-level resolution diagnostic if a relative value
unexpectedly lacks an unambiguous required source/base. Defaults are a known
case, not missing provenance. Do not copy the upstream example's optional
warning-and-leave-relative fallback or impose confinement on application
paths. Queries are callback-scoped; detached records may be retained, but
never retain the `Resolution` context for post-load queries.
6. Enable imports and selected profiles on the public new loader, using
`File` and the selected file's canonical directory as the root. Keep CLI
references runtime-owned and use ConfigKit's composition semantics directly.
**Acceptance:** root, fragment, and overlay values resolve from their own files; **Acceptance:** root, fragment, and overlay values resolve from their own files;
inherited values retain their base origin; profile-replaced sequences use the inherited values retain their base origin; equal-valued replacements identify
new declarations; normalized enclosing IDs do not lose attribution. Effective their new source; profile-replaced sequences and normalized enclosing IDs retain
and explanation output agree with the actual paths. Removed/overridden file attribution. Destinations follow the same rule as references. Defaults use the
values are not opened or resolved. Root containment affects only ConfigKit main directory; CLI overrides use the invocation directory. Effective and
configuration sources. explanation output agree with runtime. No second load or new file-access policy.
**Validation:** `go test ./internal/core/config ./internal/framework/pipeline`. **Validation:** `go test ./internal/core/config ./internal/framework/pipeline`.
Use temporary configuration trees with same-named reference files in different Use temporary trees with same-named references in different directories,
directories, aliases/symlinks accepted by ConfigKit, profile replacements, canonical symlink targets accepted by ConfigKit, profile replacements,
normalized keys, and absolute external paths outside the config root. Use real normalized keys, default and CLI destinations, empty cache paths, and absolute
reference materialization for one case to prove the intended bytes are chosen. paths outside the config root. Change the working directory in a controlled
test to distinguish the bases. Materialize a real reference in one case to
prove the intended bytes are chosen. Protect Notarius policy at the load
boundary; generic fixed-view/record-detachment tests remain upstream.
**Prompt size:** Medium, with a firm upstream gate; no CLI or example migration. **Prompt size:** Medium; one shared path-base helper and its typed consumers,
with no CLI activation or example migration.
## Stage 8 — Prepare Shared CLI Loading And Diagnostics ## Stage 8 — Prepare Shared CLI Loading And Diagnostics
@@ -392,7 +408,8 @@ reference materialization for one case to prove the intended bytes are chosen.
1. Add a CLI helper that discovers the file, passes profile selection and 1. Add a CLI helper that discovers the file, passes profile selection and
explicit override records to the new loader, and returns `LoadedConfig` explicit override records to the new loader, and returns `LoadedConfig`
plus the selected config path. Keep discovery order and injected test lookup. plus the selected config path. Supply the invocation directory needed for
relative CLI overrides. Keep discovery order and injected test lookup.
2. Add a shared load-error reporter using `errors.As` for ConfigKit load errors 2. Add a shared load-error reporter using `errors.As` for ConfigKit load errors
and `WriteDiagnostics`; supply safe source context using the dependency's and `WriteDiagnostics`; supply safe source context using the dependency's
source records. Do not flatten multi-error output into repeated wrappers or source records. Do not flatten multi-error output into repeated wrappers or
@@ -469,12 +486,16 @@ incompatible generated references.
4. Convert both maintained D&D example configurations to v5 object syntax in 4. Convert both maintained D&D example configurations to v5 object syntax in
place, still as self-contained files in this stage. Change the complete place, still as self-contained files in this stage. Change the complete
example's PromptKit source path for declaration-relative interpretation. example's PromptKit source path for declaration-relative interpretation.
Review destination paths in both examples: retain their declared relative
strings unless an example's intended location requires a deliberate change;
explain their new configuration-file base.
5. Migrate run/reference/state tests and the maintained-example loader to v5. 5. Migrate run/reference/state tests and the maintained-example loader to v5.
Split mechanical fixture updates from behavioral assertions within the Split mechanical fixture updates from behavioral assertions within the
diff so regressions remain reviewable. Retired env-based tests now supply diff so regressions remain reviewable. Retired env-based tests now supply
YAML or explicit flags; keep one test proving those variables have no effect. YAML or explicit flags; keep one test proving those variables have no effect.
6. Update current CLI, configuration, operations, and consumer references for 6. Update current CLI, configuration, operations, and consumer references for
v5, profile selection, environment retirement, and `effective-config.yml`. v5, profile selection, environment retirement, path bases (including defaults
and destinations), and `effective-config.yml`.
**Acceptance:** all production commands use the new helper; imported/profile **Acceptance:** all production commands use the new helper; imported/profile
configuration and explicit overrides agree with execution and debug output; configuration and explicit overrides agree with execution and debug output;
@@ -658,43 +679,32 @@ unnecessary for a configuration migration.
**Prompt size:** Medium; verification and focused documentation reconciliation, **Prompt size:** Medium; verification and focused documentation reconciliation,
with no planned production redesign. with no planned production redesign.
## Upstream Prerequisite ## Released API And Readiness
### Source Origins During ConfigKit Resolution ConfigKit v0.3.0 provides both required query methods in its public
`lifecycle.go`:
**Evidence:** In v0.2.0, `Resolution` exports `IsExplicit`, `Record`, `Error`, - `(*Resolution).InputInfo(Path) (FieldInfo, bool)`: fixed decoded entry
and `Warning`, with generic `Default` and `Normalize` helpers. It does not metadata, including retained defaults and explicit null; missing or
expose source metadata. `Result.Metadata()` and `Result.Sources()` become shape-mismatched paths return false.
available only after `Load` returns. Mutating `Result.Config` afterward does - `(*Resolution).Source(string) (SourceInfo, bool)`: detached acquired-source
not change `WriteEffective` or `WriteExplanation`, which use frozen snapshots. records; empty/unknown IDs return false; non-file sources have no invented
Therefore a single v0.2.0 load cannot both use declaration origins to normalize filesystem path.
paths and record that normalization in ConfigKit's inspection history.
**Selected approach:** Request a small upstream API exposing surviving Both methods are callback-scoped and perform no new filesystem or credential
input origins and canonical source records during the existing resolution lookup. Their entry-state contract permits querying original paths even after
callback. It should distinguish base/profile/CLI/default origins, identify the map-key normalization. Existing `Normalize`/`Record` and result renderers
declaring file for a scalar, and permit lookup at original paths before complete the one-load workflow; no upstream extension remains outstanding.
application map-key normalization. Keep the existing recorded mutation API.
Exact method names and the containing release must be confirmed upstream;
none are assumed to exist by this plan. This preserves one load, ConfigKit
ownership of composition/provenance, and the agreed effective-output contract.
The tradeoff is an upstream release dependency at Stage 7. This plan does not
authorize changes to the sibling repository.
**Alternative considered:** Stay on v0.2.0 and resolve paths in the narrow Notarius Review `docs/releases/v0.3.0.md`, the recorded-resolution contract in
runtime converter using completed-result metadata. Preserve original document `docs/config.md`, and `examples/consumers/consumers.go` /
paths for origin lookup. Present ConfigKit's effective configuration as a `consumers_test.go` in the pinned dependency. The example demonstrates
logical configuration view, and expose resolved runtime paths separately in `LoadNotariusPaths`; adopt its public-API usage, not its optional fallback
debug/inspection output. This is implementable without an upstream change and policy. Its warning-and-leave-relative behavior is not the Notarius contract.
keeps composition centralized, but changes the agreed inspection contract,
requires Notarius to own the extra path report, and cannot make ConfigKit's
explanation record the post-load normalization. It requires explicit approval
and revision of Stage 7 and the feature roadmap before dependent work begins;
the user selected the upstream extension instead.
Do not resolve this by silently dropping imports/profiles, changing all file The public-facade refactor needs no consumer migration; do not reach into the
paths to working-directory-relative, reparsing YAML, or performing a second private engine. Go 1.25 compatibility and the private YAML v4 prerelease pin
load that might observe different files. All other product decisions in this are unchanged. Upstream macOS support is best-effort, matching Notarius policy;
plan are settled; the upstream release is the sole remaining gate. No product do not add platform gates as part of this adoption.
questions remain open. Once the API is released, review its exact signatures,
update the pinned version and this stage's API mapping, and then resume Stage 7. No open product decisions or upstream prerequisites remain.