Remove completed configuration control plans

This commit is contained in:
2026-11-02 01:02:13 +00:00
parent c63f4ff687
commit 7ed4629c8d
3 changed files with 3 additions and 595 deletions

View File

@@ -55,6 +55,7 @@ these uses without a new inspection-record format. Consumers must migrate
genuine old control blocks and account for source-root application fields
named `config`; ordinary nested and assembled root fields remain available.
The [feature roadmap](../roadmap/config-directives.md) records the target and
the [implementation plan](../roadmap/implementation.md) tracks its progress.
The completed feature roadmap and implementation plan are preserved in Git
history at `c63f4ff` under `docs/roadmap/`, for example
`git show c63f4ff:docs/roadmap/implementation.md`.
The [configuration contract](../config.md) owns implemented behavior.

View File

@@ -1,235 +0,0 @@
# Document-Root Configuration Controls
Status: implemented. The `config` spelling and source-document-root-only
reservation are in effect. Ordinary application-root `config` data created
through placement or later lifecycle operations is permitted.
Planning baseline: `1e69abc88cf748537cd7febc85e0743755fa2fc1`.
## Purpose
Use `config` for ConfigKit's document-level controls while allowing applications
to use nested `config` fields for their own settings. An application that selects
ConfigKit adopts one control syntax; it should not need a configurable keyword
or a second configuration-processing pass.
This roadmap records the target and rationale. The [implementation plan](implementation.md)
records execution and validation. The [configuration contract](../config.md)
and public Go declarations own current behavior.
## Prior Baseline
At the planning baseline, ConfigKit used a root `configkit` mapping for `imports`
and `sequences` controls, extracted before placement and composition. Nested
occurrences of `configkit` were rejected, including within application mappings
and sequences. Imports-disabled and selected-overlay paths enforced that
reservation separately.
The reservation also reached beyond parsing:
- [Destination validation](../../internal/engine/destination.go) rejects
`configkit` in every segment. Its helpers also serve import destinations,
collection declarations, and exact application identity registrations.
- [CLI override validation](../../internal/engine/override.go) rejects the name
in paths and recursively inside supplied values.
- [Source-version processing](../../internal/engine/source_version.go) protects
actual source-root controls from overlapping version declarations.
- Source inspection records, diagnostics, examples, and documentation use
source-local paths such as `/configkit/imports/0`.
A constant rename alone would retain the broad prohibition under a much more
common application field name. The scope change is an essential part of this
migration.
## Targeted End State
### One source-document control block
`config` replaces `configkit` as the exact, case-sensitive name of a control
mapping at a source document's root:
```yaml
config:
imports:
- path: fragments/provider.yml
destination: [providers, primary, config]
sequences:
- destination: [jobs]
key: id
```
Recognize the block in each participating input document before mounting its
application payload. This covers host files, native filesystem files, byte and
reader input, mapping sources, imported fragments, underlays, and selected
overlays through the existing loading paths. A mapping source's root is its
source-document root even though it was not parsed from YAML.
Retain the existing control fields and their context-specific rules. Imports
remain opt-in; sequence declarations remain available where currently supported;
selected overlays continue to allow collection declarations and reject imports.
Malformed blocks and unknown control fields remain errors under the existing
diagnostic families. This change adds no shape-based fallback that treats an
unrecognized root `config` as application data.
Remove the control block from the source payload as part of existing directive
extraction. Placement, composition, inheritance, decoding, CLI assignment, and
application callbacks retain their established order. They do not start another
document-control discovery pass.
### Nested application fields
Below a source's root, `config` is ordinary application data. For example:
```yaml
providers:
primary:
config:
timeout: 10s
imports: application-owned-value
```
Neither nested `config` nor the field named `imports` above acquires control
semantics. Its contents follow normal schema, combination, presence, validation,
and inspection rules. The same applies inside sequence records, overlays, and
inherited application payloads. Fields inside the actual root control block
continue to follow that block's grammar.
The boundary belongs to the source document, rather than its eventual mounting
location. An imported file's own root `config` is still its control block even
when that file becomes a nested mapping or a sequence item. To supply the
provider settings in the first example, `fragments/provider.yml` can contain
`timeout: 10s`; the destination places that payload under
`/providers/primary/config`. Its filesystem paths still resolve from the
declaring file under the existing resource-context rules.
### Application-root data from non-document operations
Input placement, mounted imports, typed defaults, CLI overrides, and application
resolution may produce ordinary `config` data at the final application root,
following their existing schema and lifecycle rules. Controls are recognized
only during source-document extraction. For example, a fragment containing
`timeout: 10s` can be placed at destination `[config]`, producing application
data at `/config/timeout`. A CLI assignment to `Keys("config", "timeout")`
addresses that data rather than introducing a control. Collection declarations
and registrations can likewise address actual data at that application path.
This keeps the reservation document-local. Placement and later lifecycle
operations do not reinterpret their output as another source document, and no
additional schema or callback restriction reserves the final root namespace.
Inspection can show a root `config` value without reinterpreting it; effective
YAML retains its existing lack of a reloadability guarantee. Explain
source-local control coordinates and assembled application coordinates
separately, even when their path text is the same; this requires no new
inspection-record format.
### Consistent application-path handling
Allow application paths containing literal `config`, at root or nested, in
input placement, relative import destinations, collection declarations and
registrations, CLI paths and values, version fields, and inspection queries.
Each operation retains its existing rules. In particular, a relative destination
beginning with `config` can legitimately refer to a nested application mapping
after the parent destination is applied. Do not decide its meaning from that
relative segment alone.
Protect actual source-root controls during source-version extraction while
allowing version fields below an ordinary nested `config` mapping. Preserve
main-version ownership, non-main header consumption, and existing version modes.
An assembled application path beginning with `config` does not by itself
establish overlap with an actual source-document control block.
`extends` keeps its existing inheritance meaning, scope, and CLI restrictions.
Allowing `config` in application data does not make other invalid paths, unknown
typed fields, malformed controls, or overlapping version writes valid.
### Direct migration and observable records
Use one control spelling. `configkit` and the earlier `_configkit` spelling are
ordinary application keys, with no compatibility alias or special legacy-key
rejection. They are accepted or rejected by normal application schema rules.
Consumers must update their actual control blocks; a permissive mapping schema
may accept an old block as data without executing its imports.
Directive-related paths in diagnostics and source evidence change to the new
spelling, such as `/config/imports/0`. Preserve authored locations, source IDs,
effective placement, history, sensitivity, and resource ownership. Application
values under root or nested `config` receive the same metadata and safe
inspection as other ordinary fields, including explicit false, zero, empty,
and null values where supported by the schema.
The Go package name, vanity module path, exported symbol names,
`configkit:"secret"` struct tag, and library diagnostic prefix remain unchanged.
This is a configuration-control syntax and reservation-scope migration.
## Work Needed From the Baseline
### Engine integration
Update directive extraction and imports-disabled/overlay checks together so
they recognize source-root `config` and stop rejecting ordinary nested keys.
Review the old recursive rejection helpers for removal or simplification where
they no longer serve the selected rules.
Audit destination and collection-selector validation, CLI path/value checks,
and version/control overlap detection as a coordinated change. Retain shared
helpers when their callers need the same rule; distinguish source-local control
coordinates from effective application coordinates where their responsibilities
differ. Do not carry a global name ban into a helper merely by replacing its
string constant. Allow ordinary application-root `config` data through
placement and later lifecycle operations without re-extracting controls.
Keep the existing engine and facade boundaries. No configurable control name,
new provider abstraction, or change to composition algorithms is needed.
### Documentation and migration
Record the document-root boundary and its rationale in a new ADR, keeping
existing accepted decisions as historical records. Update applicable local
architecture-policy descriptions when the behavior lands. The current
[configuration reference](../config.md), public comments, and
[consumer guide](../consumers/README.md) should explain the new syntax,
per-source root boundary, ordinary nested fields, and application-root data
created through non-document operations together.
Migrate maintained examples, fixtures, and behavioral expectations for genuine
control blocks. Preserve literal `configkit` occurrences that identify the Go
package, struct tag, diagnostic prefix, or ordinary application data. Include
consumer guidance for renaming old controls, moving conflicting root application
fields, and updating stored source-local directive paths. Historical tags and
release records retain their original syntax.
Treat the syntax migration as a breaking pre-v1 change under the
[release policy](../policy/release.md#versioning-and-compatibility), intended to
land before v1.0.0. Explain it in that release's eventual upgrade guidance;
this roadmap does not prepare or publish a release.
### Behavioral verification
Use the existing [test owners](../development.md#task-to-test-map) and extend
behavioral coverage at the boundaries this change affects:
- New root controls work across the supported source forms, enabled imports,
layered inputs, mounted records, and selected overlays. Invalid controls and
imports-disabled behavior retain their established classifications.
- Nested `config` values work with imports enabled and disabled, in mappings
and sequence records, and through composition, overlays, inheritance, CLI,
defaults, and recorded resolution. Control-looking children remain data.
- Mounted inputs and relative destinations distinguish source roots from
application paths, including a relative destination beginning with `config`.
Collection registrations and nested version fields follow that distinction.
- Placement, defaults, CLI overrides, and recorded resolution can produce
ordinary application-root `config` data. Collection declarations,
registrations, and inspection can address it. Source controls are still
extracted before mounting and are not rediscovered in the resulting data.
- Ordinary `configkit` and `_configkit` data no longer trigger controls or
name-based rejection. Genuine old control syntax is not executed as an alias.
- Source-local directive evidence uses `/config/...`; ordinary application
presence, origins, explanations, sensitivity, and resource contexts agree
with final values. Existing inheritance and protected-version checks remain
effective.
Verify behavior with independent expectations, rather than a test that only
checks a renamed constant. Reuse existing coverage for unchanged semantics, run
the appropriate focused checks and everyday validation, and check documentation
links. No new release gate, security guarantee, or performance threshold follows
from this roadmap.

View File

@@ -1,358 +0,0 @@
# Implement Document-Root Configuration Controls
Status: complete.
Implementation baseline: `b27fe0598a9540ad05eefe2868a5a243eb28111e`.
The [feature roadmap](config-directives.md) owns the target and its rationale;
this document owns execution order and verification.
## Working rules and settled decisions
Follow the [development guide](../development.md), [agent policy](../policy/agents.md),
[architecture policy](../policy/architecture.md), [testing policy](../policy/testing.md),
and [documentation policy](../policy/documentation.md). This is one end-to-end
sprint. Intermediate stages may leave compilation or existing fixtures broken;
do not introduce compatibility code, skip tests, or weaken assertions to make
an intermediate stage green. Use focused checks as their fixtures become ready,
then run the complete development check at the end.
The following decisions are settled:
| Input or operation | Target behavior |
| --- | --- |
| Root `config` in any acquired source document | Parse as the document's control mapping before placement, preserving the existing context-specific fields, validation, and import opt-in. |
| Nested application `config` | Ordinary data, including inside sequence records and selected overlays. Children named `imports` or `sequences` do not activate controls. |
| A source mounted beneath an application destination | Interpret that source's own controls first; its mounting location does not change its document root. |
| Application-root `/config` produced by placement, defaults, CLI, or resolution | Ordinary data. Do not re-extract controls from assembled or typed values. |
| `configkit` and `_configkit` application keys | Ordinary data at any depth, with no control alias or special legacy-key error. Normal schema and other structural rules still apply. |
| `extends` | Preserve its existing inheritance semantics and restrictions, including CLI rejection. |
| Source versions | Protect actual source-local controls; retain existing header modes, conversion, main ownership, consumption, and disclosure rules. A matching application-path spelling alone is not control overlap. |
Keep exported signatures, the module/package name, `configkit:"secret"`,
diagnostic identifiers, and the `configkit:` library error prefix. Preserve
composition, ordering, limits, ownership, and secret-handling behavior. Do not
add keyword configuration, control discovery after acquisition, public record
fields, runtime watchers, dependencies, or release gates.
When migrating literals, distinguish root control syntax and control-evidence
paths from package imports, struct tags, error text, ordinary application keys,
and application paths. A repository-wide replacement of `configkit` or
`configkit:` is incorrect. Keep useful old-spelling inputs as positive ordinary
data regressions. A former rejection test needs a deliberate new expectation;
renaming its input while retaining the old rejection is not sufficient.
## Stage 1 — Record the agreed architectural boundary
**Status:** Complete.
**Scope:** one decision record, without changing current-behavior documentation.
1. Create `docs/adr/0020-document-root-controls.md`, using the repository's ADR
format, status Accepted, and the date of authorship. Record the decisions in
the table above: per-source root recognition, ordinary nested and assembled
root data, and one canonical spelling.
2. Explain the source-local versus application-coordinate distinction and why
placement and later lifecycle operations do not create another parsing pass.
Keep the decision focused on ConfigKit. Discuss rejected choices only under
Alternatives Considered; avoid framing the decision around downstream apps.
3. Identify the reservation-scope portion of ADR 0011 as amended, while retaining
its placement decisions. Update only that earlier ADR's status section with
a link to the new decision and a statement that its other decisions remain
in force. Leave accepted decision bodies and historical release notes intact.
**Complete when:** the ADR records the approved scope, including ordinary
application-root data, without claiming implementation is finished. Add its
development-guide navigation with the final documentation stage.
## Stage 2 — Implement source-root control extraction and guards
**Status:** Complete. Focused document-root control and extraction tests pass.
**Owners:** [directives.go](../../internal/engine/directives.go), its callers in
[acquisition.go](../../internal/engine/acquisition.go) and
[selected_overlay.go](../../internal/engine/selected_overlay.go), and focused
directive/declaration tests.
1. Change the engine's control-key constant to `config`. Keep the existing
`parseRootDirectiveBlock` grammar and context distinctions. Root extraction
must clone/remove the selected block as before and return the remaining
application body without recursively rejecting names in that body.
2. Remove `nestedDirectiveDiagnostics` and `disabledNestedDirectiveDiagnostics`
once their callers no longer need them. Make both imports-disabled guard
paths inspect only the original document's root. Preserve the distinction
between ordinary/layered sequence declarations and the private imports-only
extraction context. Root imports with imports disabled still fail.
3. Make `overlayDirectiveDiagnostics` inspect only the original overlay root.
Preserve its current root acceptance rules and diagnostics, including the
allowed collection-only block and rejected imports. Nested application
`config` values must not trigger overlay-directive errors.
4. Check acquisition call sites so these guards receive acquired source trees,
not placed or composed application trees. Preserve extraction before
mounting and existing processing-result reuse; add no second extraction
pass. Leave source-version overlap changes to Stage 4.
5. In a focused `internal/engine/directive_scope_test.go`, cover a valid new
root block; nested `config` with control-looking children in a mapping and
record; ordinary old spellings; malformed/unknown root controls; disabled
imports; and overlay root restrictions. Reuse existing declaration fixtures
for their detailed grammar and migrate the literals needed by these tests.
**Complete when:** these focused cases distinguish source roots from data, with
unchanged error families for still-invalid controls. Removing a recursive guard
must not remove validation of fields inside the actual control block.
## Stage 3 — Permit application paths and CLI data
**Status:** Complete. Focused destination, registration, and override tests pass.
**Owners:** [destination.go](../../internal/engine/destination.go),
[sequence_registration.go](../../internal/engine/sequence_registration.go),
[override.go](../../internal/engine/override.go), and their existing tests.
1. Remove the `configkit` name ban from `normalizeDestination`; do not replace
it with a `config` ban or an application-root prefix check. Retain path
validity, mapping-key normalization, explicit-index rejection, and the
existing `extends` restriction. This applies to root and nested destinations
and to relative suffixes beginning with `config`.
2. Let exact and wildcard identity registrations use literal `config` and
`configkit` segments through the shared validation. Preserve wildcard
matching, identity normalization, conflicting-registration checks, and
final sequence validation. YAML declarations inherit the same path change.
3. Remove `pathContainsDirective` and its CLI path rejection. Preserve the
independent inheritance-path check. Narrow recursive override-value control
detection to its continuing `extends` responsibility; `config` and old
spellings are ordinary data anywhere in a CLI value. Simplify private names
and parameters where the removed responsibility makes them misleading.
4. Keep CLI type checking, root-path/index restrictions, overlap detection,
protected-version checks, labels, accounting, and assignment order intact.
Ordinary root data at `Keys("config")` is not the empty/root override path.
5. Revise destination, registration, and override tests. Move formerly invalid
`configkit` cases into positive data cases. Where a table still needs a
reserved-key rejection, use the continuing `extends` rule rather than
treating `config` as reserved application data. Cover root and nested
`config`, relative suffixes, exact/wildcard registrations, and CLI values
containing ordinary `imports`/`sequences` fields. Retain meaningful negative
cases for indexes, invalid paths, inheritance controls, and version writes.
**Complete when:** literal application keys work through the shared path APIs
without a new per-caller exception or configurable reservation policy. Typed
defaults and resolution must not gain a new schema/key rejection.
## Stage 4 — Verify source-version and acquisition integration
**Status:** Complete. Focused source-version and declaration-overlap tests pass.
**Owners:** [source_version.go](../../internal/engine/source_version.go),
`processAcquiredInputVersion` in acquisition, import processing, and existing
source-version/item-policy tests.
1. Use the new control constant in actual source-root overlap detection. Keep
`sourceVersionHeaderControlOverlap` tied to an observed source-local header
and the original source tree. Preserve malformed-control validation before
a checker can consume that content, along with `extends` overlap handling.
2. Trace ordinary, layered, imported, sequence-item, and overlay processing.
Retain the distinction between local version lookup and effective main
ownership after mounting. Do not add a preflight ban on a version path merely
because it contains or begins with `config`.
3. Migrate the source-version test inputs and source-local expected paths.
Preserve absent/null behavior, callback order, consumption of accepted
non-main headers, conservative error/callback redaction, and existing codes.
4. Add focused cases for a header under an ordinary nested `config`; a real
header inside root `config.imports` being rejected before its checker; and
an enabled-mode main with local `version: 4` mounted at `[config]`. For the
mounted case, check the local header, final `/config/version`, and rejection
of an override targeting that protected application path. Include an
assembled-root case under the default mode using its existing effective-path
rule, rather than changing MainOnly semantics to match enabled modes.
**Complete when:** application-root data and source-root controls are not
confused by version checking. Existing version behavior needs no new mode,
schema exception, or record format. Run focused SourceVersion tests once their
affected fixtures have been migrated.
## Stage 5 — Migrate engine source and acquisition fixtures
**Status:** Complete. Focused acquisition, import, destination, and source tests pass; structural fixtures remain for the next stage.
**Scope:** remaining engine source/discovery/import/placement/resource-context
tests and acquisition-related benchmarks, excluding structural/history fixtures
assigned to Stage 6.
1. Migrate genuine root control blocks in import specs, import discovery and
evidence tests, filesystem/equivalence tests, discovery-load tests,
destination/import lifecycle tests, and standalone/grouped acquisition
tests. Cover escaped Go strings, raw multiline YAML, and mapping-source
keys; do not rely on a root-line text replacement alone.
2. Update expected declaration/empty-selection paths and coordinates to the
new source-local spelling. Preserve source labels and IDs, physical paths,
namespace identity, acquisition order, and effective destinations.
3. Convert nested-name rejection cases into ordinary-data cases where required.
Keep the file/containment/permission/repetition/limit tests testing their
original risks with valid new control syntax.
4. Include an acquired fragment with its own `config` controls mounted below a
nested destination or as a record. Include a payload mounted at root
`[config]` and a transitive relative destination starting with `config`.
Check successful assembly and source/resource attribution using existing
filesystem test patterns, without a mock traversal-count requirement.
**Complete when:** these tests reach the behavior they intend to exercise with
the new grammar. Run the relevant Source/Import/Glob/Discovery/Destination/
Resource tests; defer unrelated stale structural fixtures to Stage 6.
## Stage 6 — Migrate engine structural and inspection fixtures
**Status:** Complete. The engine suite passes, including composition, inheritance, and source-evidence regressions.
**Scope:** remaining engine composition, collection, inheritance, lifecycle,
history, provenance, explanation, sensitivity, and rendering tests/benchmarks.
1. Migrate genuine root controls and control-path expectations in the remaining
engine fixtures, including collection declarations, overlay policy,
inheritance-policy propagation, and item-local policy cases. Preserve
application keys and Go secret tags. Rename fixture comments when they
describe the changed syntax, not the library identity.
2. Retain the existing strict-peer, precedence, collection-operation, and
inheritance assertions. Upsert remains whole-record replacement; the
namespace change does not authorize a different combination algorithm.
3. Extend existing behavioral owners to cover ordinary `config` data surviving
strict composition, a higher-tier override, and sibling inheritance. Verify
explicit false/zero and representative permitted empty/null values at these
paths; reuse existing presence tests rather than constructing a Cartesian
product of every input kind and lifecycle operation.
4. Verify value inspection and source-local control evidence can coexist even
when path text shares a `/config/...` prefix. Use the existing source IDs,
locations, and record contexts; do not invent a path-kind flag or format.
Preserve historical redaction and snapshot ownership through existing test
coverage, adding a scope-specific case only where that coverage leaves a gap.
**Complete when:** the engine suite passes with no obsolete global-name
rejections or control aliases. Run `go test ./internal/engine`; use the final
stage for the complete repository check.
## Stage 7 — Update facade fixtures and public integration coverage
**Status:** Complete. The root package suite passes, including external public integration regressions.
**Scope:** root facade tests and executable package examples.
1. Migrate root-level test and example inputs that intentionally use controls,
including source equivalence, import-default evidence, mounted collections,
version modes, diagnostics, and underlay-origin fixtures. Update expected
source-local paths, preserving package names, error prefixes, and secret tags.
2. Add public API regressions in `facade_config_directives_test.go`, using the
external `configkit_test` package and independently authored expectations:
- A normal load with a new root control and nested typed `config` data.
- A declared import mounted at `[config]`, with ordinary data children named
`imports` or `sequences`. It must not attempt another import pass.
- Defaults-only loading with a typed root `config` field, an explicit CLI
false/zero assignment below it, and a recorded resolution change. Check
entry-state versus final presence/origins and effective values through the
existing public APIs.
- Old spellings as normal data, including a control-looking old block whose
nonexistent import is not executed. Use a permissive schema for this
positive case; separately retain strict unknown-field failures.
3. Use the mounted case to verify import-declaration evidence, final data
lookup, explanation, and effective output describe their proper contexts.
Include a field tagged `configkit:"secret"` under application `config` and
verify ordinary hiding still applies. Do not compare full incidental error
wording or add duplicate engine tests for every parser shape.
4. Keep root facade conversions and exported signatures unchanged unless a
genuine existing conversion bug is exposed; this feature requires no new
bridge API or inspection fields.
**Complete when:** `go test .` passes, including executable API examples and
public/import-boundary checks, with working external use of root and nested
application `config` data.
## Stage 8 — Migrate maintained consumer fixtures and show the boundary
**Status:** Complete. The consumer examples and executable tests pass.
**Scope:** `examples/consumers`, its YAML fixtures, and their executable tests.
1. Migrate genuine root controls in consumer fixtures and inline generated
documents. Update expected declaration paths or displayed errors as needed;
retain domain behavior, application-owned profile concepts, and the existing
source/resource ownership assertions.
2. Add `Example_documentRootConfig` in
`examples/consumers/config_controls_test.go`. Use a small `fstest.MapFS` main
document with `config.imports`, importing a fragment containing ordinary
settings at destination `[config]`. Decode into an application type with a
`yaml:"config"` field and show the resulting value. The example demonstrates
that the source control is consumed while the fragment becomes root data.
Keep the example offline, credential-free, and small enough to copy.
3. Preserve existing complete consumer examples instead of adding a parallel
loader abstraction. Use existing imports, destinations, and recorded-helper
conventions without a second application-side merge.
**Complete when:** `go test ./examples/consumers` passes, including the new
executable example. Existing scenarios still exercise their original features.
## Stage 9 — Update current documentation and public comments
**Status:** Complete. Current documentation, navigation, and public comments reflect the implemented boundary; local links and examples pass.
**Scope:** canonical behavior, local architectural descriptions, consumer
migration guidance, and navigation after the implementation is in place.
1. Update the configuration reference's imports, overlays, destinations,
collection declarations/registrations, CLI, version overlap, and earlier
directive spelling sections as one consistency pass. Replace the obsolete
nested-key prohibition with the per-source root boundary. Explain ordinary
application-root data and the existing non-reloadability of inspection YAML.
2. Show a source-root control beside a nested application `config`, and link
the maintained mounted-root example. Explain that every imported file has
its own root, even when mounted below another value or as a sequence item.
3. Add consumer migration guidance: rename genuine old control blocks; move,
rename, or separately mount source-root application fields formerly named
`config`; update stored `/configkit/...` declaration paths to `/config/...`.
Old blocks can decode as data in permissive schemas and no longer execute
controls. Preserve historical release notes and accepted ADR bodies.
4. Update relevant public Go comments and local architecture-policy wording
for source-local controls versus application data. Keep exact YAML rules
in the configuration reference. Explain only affected implementation flow
in internal docs; add the ADR and example to existing development/consumer
navigation. Review README examples and links for any obsolete control syntax.
5. Leave unrelated policy language, licensing, module identity, Go minimum,
dependencies, release commands, and release gates unchanged. Do not prepare
v1.0.0 notes or publish anything during this sprint.
**Complete when:** current docs, declarations, and examples agree on both the
spelling and the boundary, with historical records clearly historical. Keep
implementation progress in this plan; the feature roadmap remains an end-state
document.
## Stage 10 — Complete the integration and scope review
**Status:** Complete. Reviewed the implementation and retained old spellings in context; `./scripts/check.sh` passed with Go 1.26.8 on Linux, including formatting, whitespace, tests, vet, and build.
1. Search current production code, tests, examples, and docs for old root
controls, recursive name bans, and stale declaration paths. Review each
remaining old spelling in context; retained package names, tags, error
prefixes, ordinary data tests, and historical records are intentional.
2. Review the complete result against the settled-decision table. In particular,
prove new source controls work across supported source forms; nested and
constructed root data are accepted; controls are interpreted before
placement; CLI/collection/version checks use the right coordinates; and
`extends`/protected-version restrictions remain effective. Use the owning
tests from prior stages instead of adding another duplicate integration suite.
3. Review for unintended scope changes: no source-root data fallback, old-key
compatibility alias, configurable keyword, post-acquisition control parsing,
application-root schema ban, new metadata format, or changes to composition,
defaults, ownership, secret handling, limits, or ordering. Fix discrepancies
rather than altering the approved target to match the implementation.
4. Run `./scripts/check.sh` with dependencies already available. It supplies
formatting/whitespace, all tests and examples, local links, vet, and build.
Reuse successful focused checks for unchanged work; broaden testing only for
concrete unresolved risks. No benchmark, CI wait, macOS gate, or live service
check is required for this migration.
5. Review the final diff and preserve unrelated work and ignored credentials.
Record actual completion/validation in this plan and update the feature
roadmap's overall status when the whole feature is implemented, without
adding stage checklists there. Commit validated, reviewable work under the
agent policy with plain-English messages; no
empty commits, push, release tag, hosted delivery, or consumer dependency
update is part of this implementation sprint.
**Complete when:** the targeted behavior is implemented and documented, the
complete check passes, and the final review finds no remaining gap against the
feature roadmap. There are no unresolved design decisions in this plan.