Files
ConfigKit/docs/roadmap/implementation.md

11 KiB

Integer schema versions: implementation plan

Status: implementation complete (2026-09-12). The feature roadmap records the feature scope, the configuration contract owns implemented behavior, and 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, 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: complete (2026-09-12). 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 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:

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.

Completion record: maintained Notarius fixtures now accept integer 4 and quoted "4" with the same string-backed result. Unsupported integer 5 reaches domain policy, fractional 4.0 remains version.type, and dynamic option integers remain int64. Current documentation and Go examples were audited; canonical behavior is owned by the configuration contract and consumer guide, while historical release, extraction, and ADR records were left unchanged. The focused consumer/example commands, ./scripts/check.sh, and the full release checker pass on Linux with Go 1.25.5 and Go 1.26.7.

Compatibility handoff: exported API shapes are unchanged, but integer input at a configured version path intentionally changes from structural rejection to invoking application policy and, for plain string destinations, successful decoding. The conservative release choice is therefore a new pre-v1 minor version, subject to maintainer selection and unused-version checks. No version, note, candidate, or tag was created. Release preparation must still select the version, create and approve matching notes, retire these completed roadmap files, rerun Linux and native macOS checks on the exact candidate commit, push and guard that commit, publish the exact tag, and verify clean consumer retrieval.