Files
ConfigKit/docs/roadmap/implementation.md

170 lines
9.7 KiB
Markdown

# Integer schema versions: implementation plan
Status: in progress. The [feature roadmap](integer-schema-versions.md) owns the
intended behavior and architecture; this document owns execution and progress.
## Execution rules
Execute stages sequentially. Each stage is a bounded assignment for one
gpt-5.6-terra coding agent: one coherent outcome, targeted files, focused tests,
and a reviewable handoff. Do not delegate or parallelize dependent stages by
default. No stage authorizes changing downstream repositories or publishing a tag.
Before each stage, read [development](../development.md), the relevant task-specific
policies, the roadmap, and the preceding handoff. Inspect the worktree and preserve
unrelated work. Prefer the repository's code graph for code discovery, and verify
current symbols rather than assuming the file inventory below is frozen.
Keep every stage green: add behavioral coverage alongside its implementation, run
the stated focused commands and `./scripts/check.sh`, and update implemented
contracts in the same change. Do not relax tests unrelated to this feature.
Record files changed, commands/results, remaining risks, and the next stage here.
Commit a coherent stage when committing is authorized; otherwise hand off its diff.
## Stage 1 — Deliver the checker-to-decoder vertical slice
Status: complete (2026-09-12). Depends on: none.
Scope: `validation.go`, the private decoding plumbing in `decode.go` and
`load_result.go`, necessary private call sites, and focused version/decode tests.
- Add the shared private integer-text recognition and extend `checkVersion`
according to the roadmap. Preserve diagnostics, callback order, and public types.
- Thread per-load version-path context to recursive decoding; enable integer to
plain-string decoding only at that path. Do not mutate source/history trees or
type-wide descriptors. Keep no-rule decoder callers strict.
- Add public-load coverage for integer and string `4` into `string` and `*string`,
identical checker text, absent/null states, and unsupported version kinds.
- Keep the suite green by updating the existing integer-version rejection test in
`load_test.go`. In `examples/consumers/consumers_test.go`, remove integer input
from the structural-rejection expectation or convert it to the appropriate
success/domain-policy assertion; do not merely delete migration coverage.
- Update `Version`/`VersionRule` comments, the configuration contract's version and
conversion sections, and stale consumer claims that all integer versions must
be rewritten. Describe only behavior implemented by this stage.
Acceptance: a full load of `version: 4` with a configured rule and string-backed
field succeeds and stores `"4"`; without the rule it still fails strict decoding.
An unrelated integer-to-string field still fails. Existing accepted input remains
unchanged. Both checking and decoding are implemented before this stage is done.
Validation: `go test . -run 'Version|Decode'`,
`go test ./examples/consumers`, then the everyday checker.
Completion record: checker and load-local decoder support landed with strict
no-rule and unrelated-field behavior retained. Focused package tests, consumer
tests, and `./scripts/check.sh` pass with Go 1.26.7 on Linux. Stage 2 should expand
the scalar, destination-type, and semantic-path boundary matrix.
## Stage 2 — Close scalar and path-boundary gaps
Status: complete (2026-09-12). Depends on: Stage 1.
Scope: focused tests in `load_test.go`, `decode_test.go`, and relevant path/decoder
helpers only where those tests expose defects. Avoid broad schema refactoring.
- Cover zero, negative integer, `-0`, a decimal identifier beyond int64 range,
empty string, fractional/exponent numbers, booleans, and containers. Check parser
rejection remains separate for non-JSON numeric spellings; reuse parser coverage.
- Exercise a nonstandard nested version path, an escaped mapping key, contextual
numeric path tokens, and sibling fields sharing a named string type. Prove
conversion is path-scoped rather than descriptor-wide or name-based.
- Cover named strings and pointer wrappers; show integer destinations and dynamic
values retain ordinary types/range errors, while custom text codecs, durations,
and secret-reference destinations do not gain integer coercion.
- Verify unsupported kinds prevent the version callback, accepted integer input
reaches application policy, and rejection by that policy prevents later hooks.
Assert codes, semantic paths, and locations, not incidental message wording.
Acceptance: the target scalar/destination matrix is covered with lean table-driven
tests, no silent overflow/rounding, and no coercion leakage to unrelated fields or
loads. Expand a stage-1 test instead of duplicating the same behavior.
Validation: `go test . -run 'Version|Decode|Path'`, then the everyday checker.
Completion record: boundary coverage now includes exact zero, negative, negative
zero, unbounded textual integer, rejected scalar/container kinds, parsed numeric
tokens in maps and sequences, escaped keys, named and nested-pointer strings, and
ordinary numeric, dynamic, codec, duration, and secret destinations. Existing
parser-policy tests continue to own non-JSON number rejection. The focused command
and `./scripts/check.sh` pass with Go 1.26.7 on Linux. Stage 3 should verify retained
history, rendering, composition ownership, detachment, and redaction invariants.
## Stage 3 — Verify provenance and pipeline invariants
Status: complete (2026-09-12). Depends on: Stage 2.
Scope: `explain_test.go`, `provenance_test.go`, import/profile/override and secret
test owners as needed. Production changes only for demonstrated integration gaps.
- Add an end-to-end integer-version case asserting final string configuration,
effective string rendering, original numeric history, and the existing decoding
reconciliation event. Confirm locations, explicitness, and historical lookup.
- Exercise equal-valued defaults and detached repeated loads/queries so conversion
does not masquerade as resolution or mutate retained input.
- Verify integer versions do not bypass fragment-version rejection, profile version
protection, or CLI overlap checks; extend existing owners rather than recreating
each suite. Include a nonstandard version path where practical.
- Check sensitive original/effective version snapshots remain redacted and that
the conversion adds no secret resolution or credential-bearing diagnostics.
Use synthetic fixtures and existing lookup seams, never real credentials.
Acceptance: typed configuration, metadata, rendering, and explanation agree; the
only intentional change is the version input/decoding exception. If inspection
needs repair, retain original input rather than suppressing its history.
Validation: `go test . -run 'Version|Import|Profile|Override|Provenance|Explain|Secret'`,
`go test -race ./...`, then the everyday checker.
Completion record: end-to-end inspection now proves a numeric retained input, a
string typed/effective value, a decoding reconciliation event, exact base origin
and location, historical lookup, equal-default handling, and detached repeated
results. Integer fixtures exercise fragment, profile, and CLI version protection.
Sensitive version history is redacted and performs no credential lookup. The
focused suite, race suite, and `./scripts/check.sh` pass with Go 1.26.7 on Linux.
Stage 4 should finish the maintained Notarius evidence, canonical documentation,
and release-readiness validation without publishing a release.
## Stage 4 — Complete consumer evidence and release readiness
Status: not started. Depends on: Stage 3.
Scope: maintained Notarius-shaped examples/fixtures, consumer documentation,
documentation consistency review, and validation handoff. No downstream app edits.
- Make integer `version: 4` and quoted `version: "4"` representative successful
Notarius-shaped inputs with the same string-backed application result. Configure
the example's application checker consistently; do not bypass version policy.
- Retain negative examples for unsupported application versions and non-integer
version kinds, with stable diagnostic codes/paths. Verify unrelated dynamic
option integers and runtime conversions remain unchanged.
- Audit current documentation and Go examples for string-only claims. Keep
historical release notes, extraction records, and ADR rationale historical;
repair navigation without rewriting historical decisions. Transfer completed
target descriptions from the roadmap to canonical owners.
- Run the full release checker using the command below (or qualifying cached
toolchains selected under the release runbook). Report actual versions and results.
- Hand off the compatibility assessment and remaining release work. Select an
unused version with the maintainer; create version-matched notes only for a real
candidate. A changed rejection contract must be reviewed explicitly; do not reuse
the v0.1.1-only policy exception.
Acceptance: complete consumer regression and all available automated gates pass;
no current documentation promises unimplemented behavior. Mark implementation
complete separately from publication. Exact-commit Linux/macOS checks, candidate
commit/push, release-note approval, roadmap retirement, tagging, and clean consumer
retrieval follow the [release procedure](../release.md) when separately authorized.
Unavailable macOS evidence is a release blocker, not permission to waive the gate.
Validation: `go test ./examples/consumers`, `go test . -run '^Example'`, the everyday
checker, and the full release checker:
```sh
CONFIGKIT_BASELINE_TOOLCHAIN=go1.25.5 \
CONFIGKIT_NEWER_TOOLCHAIN=go1.26.7 \
./scripts/release-check.sh
```
Rerun exact-commit release checks after
any later candidate or roadmap-retirement changes.