Support integer schema versions through typed decoding
This commit is contained in:
152
docs/roadmap/implementation.md
Normal file
152
docs/roadmap/implementation.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 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: not started. 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.
|
||||
|
||||
## Stage 3 — Verify provenance and pipeline invariants
|
||||
|
||||
Status: not started. 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.
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user