From 8a62b42503cd10a09f4ca2f3371d40327fe42449 Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 12 Sep 2026 01:33:17 +0000 Subject: [PATCH] Prepare ConfigKit v0.2.0 --- docs/development.md | 8 +- docs/policy/release.md | 6 + docs/releases/v0.2.0.md | 58 ++++++++ docs/roadmap/implementation.md | 190 ------------------------ docs/roadmap/integer-schema-versions.md | 17 --- docs/roadmap/remediation.md | 87 ----------- 6 files changed, 67 insertions(+), 299 deletions(-) create mode 100644 docs/releases/v0.2.0.md delete mode 100644 docs/roadmap/implementation.md delete mode 100644 docs/roadmap/integer-schema-versions.md delete mode 100644 docs/roadmap/remediation.md diff --git a/docs/development.md b/docs/development.md index 66ecb5c..7ff61ba 100644 --- a/docs/development.md +++ b/docs/development.md @@ -42,11 +42,9 @@ git show cb5b435:docs/roadmap/remediation.md Release-candidate, publication, and verification work follows the operational [release procedure](release.md). -The completed string-and-integer schema-version work remains recorded in its -[feature roadmap](roadmap/integer-schema-versions.md) and -[sequential implementation plan](roadmap/implementation.md) until release -preparation retires them. The [configuration contract](config.md) owns current -behavior. +The completed string-and-integer schema-version implementation and remediation +records are preserved in Git history at `244104f`. The +[configuration contract](config.md#application-schema-versions) owns current behavior. ## Baseline validation diff --git a/docs/policy/release.md b/docs/policy/release.md index 32cde90..64fddf6 100644 --- a/docs/policy/release.md +++ b/docs/policy/release.md @@ -227,5 +227,11 @@ minor-version increment. The release note must explain the renamed directive, the lack of a legacy alias, and the newly reserved application key. This exception does not apply to subsequent releases or waive any validation or publication gate. +For v0.2.0 only, the maintainer accepted the successful native macOS check at +`244104f` for the final candidate, provided subsequent changes are documentation +only. The final candidate still requires the complete Linux release checker. +This exception waives only repeating the macOS check after those documentation +changes; it does not waive other publication or verification gates. + Candidate selection, publication, and post-publication verification remain mandatory steps in the [release procedure](../release.md). diff --git a/docs/releases/v0.2.0.md b/docs/releases/v0.2.0.md new file mode 100644 index 0000000..3093f48 --- /dev/null +++ b/docs/releases/v0.2.0.md @@ -0,0 +1,58 @@ +# ConfigKit v0.2.0 + +This release adds integer schema-version input and consistent canonical sequence +path handling. + +## Summary + +Applications can retain YAML such as `version: 4` while storing and checking their +version as a Go string. The exception applies only to the path designated by +`VersionRule`; unrelated fields keep strict decoding. See the +[configuration contract](../config.md#application-schema-versions). + +## Compatibility + +This minor release intentionally changes integer schema-version input from a +`version.type` rejection to invoking the application checker with its decimal text. +Plain string destinations at that path now accept it. Public Go API shapes, +minimum Go version, and supported platforms are unchanged. + +Parsed sequence indices now require canonical nonnegative decimal spelling. +Signed tokens such as `+0` and `-0`, previously accepted by some traversal paths, +no longer identify sequence elements. They remain valid literal mapping keys. +Version checking, decoding, and metadata matching now agree on this boundary. + +The private YAML dependency remains pinned to `go.yaml.in/yaml/v4 v4.0.0-rc.6`, +confirmed as the newest available v4 release during candidate preparation. Linux +candidate checks use Go 1.25.5 and Go 1.26.7. The maintainer confirmed native macOS +checks at `244104f` and approved carrying that result across the documentation-only +candidate changes under the [recorded exception](../policy/release.md#policy-exceptions). + +## Upgrade + +```sh +go get gitea.maximumdirect.net/eric/ConfigKit@v0.2.0 +``` + +Existing string schema versions need no configuration changes. Applications using +integer YAML versions can retain them and use a plain string field plus a +`VersionRule`. Review the application checker: it now receives integer identifiers +as text, and remains responsible for rejecting unsupported versions. Fractions, +exponents, booleans, and containers remain invalid version kinds. + +Replace signed sequence-index tokens in configured paths with canonical indices +(for example, `/versions/+0` becomes `/versions/0`). Do not change signed mapping +keys. Literal integers elsewhere still do not decode into strings, and numeric +destinations retain their existing range checks. + +## Changes + +- Added load-local, path-scoped integer-to-string schema-version decoding without + mutating original input or introducing general scalar coercion. +- Preserved numeric historical input, string effective output, decoding + reconciliation, source attribution, and secret redaction. +- Unified sequence path interpretation and added regression coverage for signed + tokens, literal mapping keys, and explicit key/index distinctions. +- Updated maintained Notarius-shaped fixtures and migration guidance for quoted + and integer version forms. +- Retired completed implementation and remediation roadmaps to Git history. diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md deleted file mode 100644 index 97285a7..0000000 --- a/docs/roadmap/implementation.md +++ /dev/null @@ -1,190 +0,0 @@ -# Integer schema versions: implementation plan - -Status: implementation complete (2026-09-12). The -[feature roadmap](integer-schema-versions.md) records the feature scope, the -[configuration contract](../config.md) 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](../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: 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](../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. - -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. diff --git a/docs/roadmap/integer-schema-versions.md b/docs/roadmap/integer-schema-versions.md deleted file mode 100644 index d66064c..0000000 --- a/docs/roadmap/integer-schema-versions.md +++ /dev/null @@ -1,17 +0,0 @@ -# String and integer schema versions - -Status: implemented on 2026-09-12; retained until release preparation. The -[implementation plan](implementation.md) records validation and stage handoffs. - -ConfigKit now accepts strings and strict decimal-integer syntax at the exact path -configured by `Definition.Version`. The application checker and a plain -string-backed destination receive the preserved text, while all unrelated decoding -remains strict. Composition ownership, source history, explanation reconciliation, -and secret redaction retain their existing behavior. - -The [configuration contract](../config.md#application-schema-versions) is the -canonical definition of the implemented behavior. The -[consumer adoption guide](../consumers/README.md) links maintained Notarius-shaped -string and integer examples. This roadmap chooses no release version and grants no -publication authority; compatibility review and roadmap retirement follow the -[release procedure](../release.md) when separately authorized. diff --git a/docs/roadmap/remediation.md b/docs/roadmap/remediation.md deleted file mode 100644 index 42bca0e..0000000 --- a/docs/roadmap/remediation.md +++ /dev/null @@ -1,87 +0,0 @@ -# Integer schema version remediation - -Review baseline: `fd8a68d`, covering implementation commits `f5bbc2b` through -`fd8a68d` against `b3e7b62`. Status: finding resolved. This document records -required corrective work, not an implemented contract or release approval. - -## R1 — Unify sequence-path interpretation between checking and decoding - -Priority: medium. Status: resolved. - -Resolution: sequence traversal now requires canonical nonnegative decimal index -tokens in the shared `schemaIndex` helper. Version decoding reuses -`matchesPathShape`, which shares that helper with traversal; its independent -numeric matcher was removed. Signed tokens remain literal mapping keys but no -longer alias sequence elements. Public-load regression coverage verifies numeric -and quoted input, metadata lookup, mapping keys, and explicit segment intent. -Focused Version/Decode/Path tests and the everyday checker passed on Linux. - -### Finding and evidence - -The new `pathMatches` helper in [validation.go](../../validation.go) implements -sequence-token matching independently of the existing `schemaIndex` helper in -[schema.go](../../schema.go). `checkVersion` looks up its node through -`documentAtPath`, which uses `schemaIndex`; typed integer-to-string conversion -instead uses `pathMatches`. - -These rules disagree. `schemaIndex` currently accepts parsed `+0` and `-0` as -sequence index zero through `strconv.Atoi`, but `pathMatches` requires the exact -canonical spelling returned by `strconv.Itoa`, namely `0`. - -A public-API probe against the review baseline used a configuration with -`Versions []string` bound to `versions`, a no-op version checker, and each path -returned by `ParsePath`: - -| Configured path | YAML value | Checker receives | Load result | -| --- | --- | --- | --- | -| `/versions/0` | `[4]` | Present, text `4` | Success | -| `/versions/0` | `['4']` | Present, text `4` | Success | -| `/versions/+0` | `[4]` | Present, text `4` | Decode failure | -| `/versions/+0` | `['4']` | Present, text `4` | Success | -| `/versions/-0` | `[4]` | Present, text `4` | Decode failure | -| `/versions/-0` | `['4']` | Present, text `4` | Success | - -Thus the checker accepts and identifies a version node, but the decoder does not -recognize that same node as the configured version path. Canonical index paths and -the ordinary Notarius `version` mapping key work correctly. The permissive lookup -predates these commits; the new, separately implemented matcher introduces the -checker/decoder disagreement. The existing canonical-index tests do not catch it. - -### Required correction - -Establish one sequence-token interpretation for version lookup and conversion, -using shared semantic-path machinery rather than independent numeric spelling -rules. Preserve explicit mapping-key versus index intent and exact string matching -for mapping keys. Do not simply substitute a helper without checking its semantics: -metadata matching also compares pointer spellings before interpreting indices. - -Decide explicitly whether noncanonical signed sequence tokens are supported or -rejected. If retaining current lookup behavior, decoding must identify the same -node. If tightening it to canonical JSON Pointer sequence indices, apply that rule -consistently to lookup and matching, document the compatibility impact, and ensure -the checker cannot report a present version that conversion refuses to recognize. -Do not broaden mapping-key matching or unrelated scalar coercion as a workaround. - -### Acceptance and verification - -- Add public-load regressions for integer and string input with canonical and - signed parsed sequence tokens, asserting checker presence/text and decoding - outcomes under the chosen policy. -- Retain coverage for literal numeric/signed mapping keys, escaped keys, explicit - `Key`/`Index` distinctions, and unrelated string fields. -- Verify lookup, version checking, and conversion share the chosen semantics; - check other users of any shared path helper changed by the fix. -- Run `go test . -run 'Version|Decode|Path'`, `./scripts/check.sh`, and the full - release checker before selecting a corrected release candidate. - -## Review validation and remaining release work - -The full release checker passed on Linux at the review baseline with Go 1.25.5 -and Go 1.26.7, including race tests, examples, documentation links, and cross-builds. -The independent public-API probe above exposed behavior outside that suite. -No production code or existing tests were modified during review. - -Release selection, version-matched notes, retirement of completed roadmap material, -and exact-candidate native Linux/macOS validation remain governed by the -[release procedure](../release.md). They are separate from resolving R1; older -release validation is not evidence for a newly changed candidate.