Prepare source release validation

This commit is contained in:
2026-09-06 22:47:12 +00:00
parent 2836f825b6
commit f42ecc70c3
21 changed files with 721 additions and 1205 deletions

View File

@@ -20,8 +20,8 @@ Use distinct strict-composition and intentional-overlay operations. Composition
rejects conflicting definitions; overlay provides explicit precedence. Keep the
operations opinionated rather than adding arbitrary per-field merge strategies.
The [architecture policy](../policy/architecture.md) owns the governing boundary;
the [target design](../roadmap/initial.md#composition-and-overlay) owns the planned
operation table until its current contract lands.
the [current configuration contract](../config.md#strict-document-composition) owns
the operation table and selected-profile overlay behavior.
## Alternatives considered

View File

@@ -20,7 +20,8 @@ ConfigKit defines its supported YAML policy and keeps parser integration private
Application types and diagnostics must not require parser-specific public types.
Use a small internal boundary rather than a general parser/provider framework.
The [architecture policy](../policy/architecture.md) owns this constraint; the
[target design](../roadmap/initial.md#yaml-and-scalar-policy) owns planned syntax.
[current YAML document](../config.md#yaml-documents) and
[scalar](../config.md#scalars) contracts own the implemented syntax.
## Alternatives considered

View File

@@ -22,8 +22,9 @@ values. Keep application defaults and normalization application-owned, but recor
resolution changes so final inspection and metadata describe the actual resolved
snapshot. Do not promise language-enforced immutability of exported Go values.
The [architecture policy](../policy/architecture.md) owns these invariants; the
[target design](../roadmap/initial.md#recorded-resolution-and-validation) owns the
planned recording mechanism and ownership semantics.
[current resolution contract](../config.md#recorded-application-resolution) and
[ownership contract](../config.md#typed-projection-and-ownership) own the implemented
recording mechanism and ownership semantics.
## Alternatives considered

View File

@@ -21,8 +21,9 @@ Existing environment variables win even when empty. Report skipped files and
partial failures without values. Keep bootstrap provenance separate from later
lookup provenance rather than imply an unchanged environment between calls.
General environment-variable configuration overlays are not on the roadmap.
The [feature roadmap](../roadmap/initial.md#secret-references-and-explicit-bootstrap)
owns the unimplemented contract; stages remain in the implementation plan.
The [current reference contract](../config.md#typed-secret-references) and
[bootstrap contract](../config.md#explicit-secrets-directory-bootstrap) own the
implemented behavior.
## Alternatives considered

View File

@@ -19,8 +19,9 @@ node tree before typed decoding, retaining the existing parser adapter boundary.
Recorded domain resolution follows input selection. Provide safe structured
historical values and an explanation renderer in the initial release, building
on ADR 0003's presence and audited resolution decision. Applications own commands.
The [feature roadmap](../roadmap/initial.md#cli-overrides) owns the exact override
contract and [explanation contract](../roadmap/initial.md#historical-value-explanation).
The [current override contract](../config.md#explicit-cli-overrides) and
[explanation contract](../config.md#historical-value-explanation) own the implemented
behavior.
## Alternatives considered

View File

@@ -567,7 +567,7 @@ executes application methods or parser-specific hooks.
Exported struct fields use an explicit `yaml` name or the lowercase Go field name.
Unexported fields and `yaml:"-"` are ignored. `omitempty` is accepted but does not
change binding or future projection. An explicit `yaml:",inline"` flattens a struct
change binding or projection. An explicit `yaml:",inline"` flattens a struct
or pointer-to-struct, or designates at most one string-keyed inline map for otherwise
unmatched names. Ambiguous names, named inline fields, multiple inline maps, and
unsupported or malformed tag options are schema errors. Embedded fields are ordinary
@@ -673,7 +673,7 @@ any sequence change reports the sequence path and never invents correspondence
between old and new indices. Cross-kind and null/container changes replace the
affected path.
These mechanisms currently support later decoding, resolution auditing, metadata,
These mechanisms support decoding, resolution auditing, metadata,
and rendering. They are not a public generic conversion or cloning API.
## Safe failures

View File

@@ -81,9 +81,9 @@ WeatherReporter, or Seriatim. Updating those repositories, their deployed YAML,
wiring, runtime catalogs, and operational documentation remains separate downstream
work.
## Maintained roadmap examples
## Maintained API examples
Every nontrivial API sketch from the feature roadmap has a compiled example or a
Every nontrivial initial API sketch has a compiled example or a
focused behavioral owner:
| Roadmap surface | Maintained owner |

View File

@@ -1,7 +1,7 @@
# Development
This is the contributor entry point for ConfigKit. Read the task-specific owners
below before making changes. The repository is in early implementation: its public
below before making changes. Its public
loader currently covers strict selected sources, explicit path/glob import graphs,
composition, selected profile overlays, typed defaults, schema-version checks,
explicit CLI overrides, recorded application resolution, semantic validation,
@@ -23,10 +23,10 @@ redacted effective rendering and historical value explanation. The
| --- | --- |
| Repository orientation or component responsibility | [Architecture policy](policy/architecture.md) and [component overview](internal/overview.md) |
| Documentation changes | [Documentation policy](policy/documentation.md) and the owning document |
| Architecture decisions or future work | [Documentation policy](policy/documentation.md), [initial target design](roadmap/initial.md), and relevant ADRs listed below |
| Architecture decisions or future work | [Documentation policy](policy/documentation.md), [initial target record](roadmap/initial.md), and relevant ADRs listed below |
| Code and test changes | [Architecture policy](policy/architecture.md), [testing policy](policy/testing.md), and owning contracts/tests as they are introduced |
| Examples or copyable assets | The owning implemented contract and [consumer adoption guide](consumers/README.md) |
| Release preparation | [Release policy](policy/release.md) and [release-readiness gaps](roadmap/release-readiness.md); the operational runbook will be added before release |
| Release preparation | [Release policy](policy/release.md), [release procedure](release.md), and [release-readiness evidence](roadmap/release-readiness.md) |
Accepted decisions:

View File

@@ -28,8 +28,8 @@ the owning implementation work extracts a symbol or case.
- Use sanitized local fixtures only. Audio, transcripts, credentials, private
configuration, and whole application package trees are application-only.
- Record the exact copied/generalized symbols and tests in the owning section when
extraction occurs. An entry below assigns evidence; it does not claim extraction
or behavior is implemented.
extraction occurs. Assignment prose records the original work boundary; dated
implementation records state what was actually generalized.
## Narratio evidence
@@ -86,8 +86,8 @@ collection, conflict construction, and recursive mapping join in `compose.go` ad
the assigned production symbols. `TestComposeDocumentsJoinsDisjointMappingsAndTracksClaims`,
`TestComposeDocumentsRejectsEveryPresentNonMappingOverlap`, and
`TestComposeDocumentsReportsAllClaimantsAtExactLocations` adapt the assigned cases.
The planned empty-mapping difference is covered separately: empty mappings retain
container provenance but contribute no child claims. No unplanned semantic deviation
The intentional empty-mapping difference is covered separately: empty mappings retain
container provenance but contribute no child claims. No other semantic deviation
from the extracted additive composer was required.
### Imports
@@ -122,9 +122,9 @@ declaration-order, disjoint composition, keyed-entry, all-source conflict, unsaf
target, alias, imported parse/schema, and relative-resolution cases. ConfigKit adds
recursive bounded DFS, `os.OpenRoot` confinement, canonical symlink identity,
cycle/diamond route locations, optional-path semantics, aggregate budgets, and
fragment version-placement enforcement. The planned glob syntax is parsed but
remains explicitly unavailable for its next owning work; hard links intentionally
replace Narratio's same-file rejection with path identity.
fragment version-placement enforcement. That checkpoint parsed glob syntax behind an
explicit unsupported gate that the subsequent glob implementation removed; hard
links intentionally replace Narratio's same-file rejection with path identity.
Glob-import implementation record (2026-09-06): ConfigKit retains the extracted
declaration order, import failures, composition, and identity cases while adding the
@@ -133,7 +133,7 @@ new `expandImportGlob`, `readGlobMatches`, and pattern-validation mechanisms in
directories, hard links, contained and escaping symlinks, unmatched declarations,
malformed and recursive patterns, escaped metacharacters, character classes,
permission failures, explicit `conf.d` use, and entry/candidate budgets. This work
has no Narratio production equivalent; it uses the planned standard-library
has no Narratio production equivalent; it uses the selected standard-library
`path.Match` and bounded `File.ReadDir` adaptation rather than its flat loader.
### Profiles and overlay
@@ -199,8 +199,8 @@ inspection cases across one default/import/profile/resolution workflow. ConfigKi
adds chronological descendant history for parent and whole-sequence operations,
composite empty-mapping origins, canonical resolution reasons/dependencies, private
snapshot agreement, defensive nested copies, and concurrent load isolation. Value
rendering, redaction, explanation, commands, generated attribution, diffs, and
digests remain assigned to their later owning work.
That checkpoint deliberately left rendering, redaction, explanation, commands,
generated attribution, diffs, and digests outside its scope.
Effective-rendering implementation record (2026-09-06): ConfigKit adapts Narratio's
deterministic effective-output and side-effect-free inspection cases in
@@ -212,7 +212,8 @@ resolved values, text-scalar snapshot reuse, application YAML-hook isolation,
non-disclosure through failures and record formatting, caller mutation, and writer
failures. Unlike Narratio's marshal/reparse path, ConfigKit renders only its owned
frozen tree and substitutes redaction before the upstream dumper boundary. Historical
value explanation and secret references remain assigned to later work.
value explanation and secret references were implemented at their later owning
boundaries and are exercised by the consumer startup example below.
### Defaults, presence, and domain resolution

View File

@@ -20,17 +20,17 @@ module and package documentation boundary. Its implemented public primitives are
- a per-operation private reflection descriptor graph in `schema.go` for supported
types, YAML field binding, inlining, secret tags, recursion, and semantic paths;
- descriptor-driven canonical projection, detached typed cloning, cycle/limit
enforcement, and structural comparison in `projection.go`; and
enforcement, and structural comparison in `projection.go`;
- strict schema-driven decoding over detached defaults in `decode.go`, including
mapping/sequence semantics, null and numeric policy, safe codec errors, presence,
baseline/final trees, and initial default/input origins; and
baseline/final trees, and initial default/input origins;
- public lifecycle coordination in `load.go`, bounded canonical import DFS in
`imports.go`, pattern-directed glob expansion in `glob.go`, version-report contexts
in `validation.go`, and detached layered metadata/history assembly in
`load_metadata.go`; and
`load_metadata.go`;
- recorded application defaulting and normalization in `resolution.go`, including
explicitness queries, helper verification, structural mutation audit, coalesced
intent, private before/after snapshots, and resolution metadata integration; and
intent, private before/after snapshots, and resolution metadata integration;
- post-resolution schema-aware report collection and validator mutation detection in
`validation.go`, completing the public callback lifecycle after composed input;
- opaque typed environment references and per-load name resolution in
@@ -38,13 +38,15 @@ module and package documentation boundary. Its implemented public primitives are
validator-state auditing;
- explicit bounded startup environment bootstrap and safe partial reporting in
`secrets.go`;
- fixed-point tag/predicate/dependency sensitivity classification in `secret.go`; and
- fixed-point tag/predicate/dependency sensitivity classification in `secret.go`;
- frozen-snapshot redaction and canonical effective output in `render.go`;
- bounded immutable input applications, safe historical replay, detached explanation
records, and deterministic human rendering in `explain.go`, with the
only upstream dumper integration isolated in `internal/yaml/write.go`; and
only upstream dumper integration isolated in `internal/yaml/write.go`;
- a separate maintained `examples/consumers` package with four sanitized consumer
shapes, fixtures, domain validators, and runtime-boundary functions.
shapes, fixtures, domain validators, and runtime-boundary functions; and
- a fail-fast source-candidate checker in `scripts/release-check.sh`, with local
documentation-link and public import-boundary gates owned by root-package tests.
The [configuration contract](../config.md) owns implemented input, schema, decoding,
loading lifecycle, path imports, composition, profile/CLI overlay, version checking,
@@ -54,15 +56,13 @@ explanation, and ownership behavior.
The [consumer adoption guide](../consumers/README.md) owns current application-fit
and migration guidance.
The source-extraction inventory records the application foundations assigned to
future implementation work:
The source-extraction inventory records the application foundations used by the
implementation:
- [Extraction inventory](extraction.md)
This document will inventory additional components and link to their current
contracts and focused internal documentation as they are introduced.
The [architecture policy](../policy/architecture.md) owns binding boundaries and
invariants. The [initial target design](../roadmap/initial.md) describes planned
behavior; it is not an inventory of implemented features. See the
[development guide](../development.md) for contributor orientation and validation.
invariants. The [initial target record](../roadmap/initial.md) links current feature
owners and preserves deferred scope; it is not an implementation inventory. See the
[development guide](../development.md) for contributor orientation and validation
and the [release procedure](../release.md) for source-candidate gates.

View File

@@ -7,10 +7,10 @@
## Purpose and applicability
ConfigKit is an opinionated Go library for consistent YAML configuration loading
and resolution across consuming applications. This policy governs contributions
now; it does not claim that the target features are implemented. The
[component overview](../internal/overview.md) owns implementation inventory and
[initial roadmap](../roadmap/initial.md) owns unimplemented target behavior.
and resolution across consuming applications. This policy governs contributions.
The [component overview](../internal/overview.md) owns implementation inventory, the
[configuration contract](../config.md) owns implemented behavior, and the
[initial target record](../roadmap/initial.md) preserves deferred scope.
## Success criteria
@@ -48,8 +48,8 @@ existing primitives cannot accommodate it cleanly, and show how the extension
preserves a coherent model. Application-specific interpretation and validation
remain appropriate. Reuse Narratio's applicable infrastructure under these
boundaries, and keep simple consumers independent of optional composition
features. The [consumer API design](../roadmap/initial.md#consumer-api-design)
describes the proposed surface; this policy does not claim it is implemented.
features. The [consumer adoption guide](../consumers/README.md) demonstrates the
implemented surface against representative simple and complex shapes.
## Responsibility boundaries
@@ -103,12 +103,12 @@ decoding. Preserve presence and source information through processing. Ordinary
values must not be used to infer whether input was absent. Final configuration,
metadata, and effective inspection must agree, including application resolution
changes; see [ADR 0003](../adr/0003-preserve-presence-and-resolution-history.md).
Safe historical values and an explanation renderer belong to the initial target,
Safe historical values and an explanation renderer are part of the implemented contract,
including superseded/deleted paths and effective source attribution. Inspection
must agree with the final typed snapshot and apply historical sensitivity rules.
See [ADR 0005](../adr/0005-explicit-overrides-and-safe-explanation.md).
Detailed syntax and operation tables belong to the target roadmap until their
current configuration contract is implemented.
Detailed syntax and operation tables belong to the
[current configuration contract](../config.md).
## Ownership and confidentiality
@@ -136,6 +136,7 @@ for safe messages supplied by their hooks.
Do not introduce automatic directory discovery, network providers, arbitrary
merge strategies, additional configuration languages, or application runtime
management without concrete consumer evidence and an explicit design decision.
The roadmap owns the complete deferred-feature inventory. Significant boundary
The [initial target record](../roadmap/initial.md#explicit-non-goals-and-deferred-scope)
owns the deferred-feature inventory. Significant boundary
changes require an ADR and corresponding policy/contract updates; implementation
convenience alone is not a reason to broaden the public API.

View File

@@ -62,24 +62,24 @@ handling, not secret values.
| Documentation rules | `docs/policy/documentation.md` | Ownership and document lifecycle |
| Testing rules | `docs/policy/testing.md` | Risk-based sufficiency, test boundaries, and maintenance principles |
| Release rules | `docs/policy/release.md` | Compatibility, integrity, gates, immutability, and exceptions |
| Release procedure | `docs/release.md`, when operational | Exact maintainer commands, prerequisites, supported targets, and verification |
| Release procedure | `docs/release.md` | Exact maintainer commands, prerequisites, supported targets, and verification |
| Exported Go API | Go documentation beside declarations | Symbol contracts, errors, ownership, and lifecycle API behavior |
| YAML and resolution semantics | `docs/config.md`, as behavior lands | Syntax, composition, precedence, conversion, secret references/bootstrap, and explanation semantics; Go reference docs link here for shared rules |
| Consumer walkthroughs | `docs/consumers/`, when useful | Task-oriented usage and consumer responsibilities, not duplicate API reference |
| Component inventory | `docs/internal/overview.md` | Implemented components and links to their owners |
| Component mechanics | Other `docs/internal/` files, when needed | Detailed implementation behavior and change recipes |
| Architectural decisions | `docs/adr/` | Context, decisions, alternatives, consequences, and supersession history |
| Initial target | `docs/roadmap/initial.md` | Unimplemented end-state and deferred feature scope |
| Initial target record | `docs/roadmap/initial.md` | Implemented-feature owner links and deferred feature scope until roadmap retirement |
| Implementation plan | `docs/roadmap/implementation.md` | Stages, dependencies, acceptance gates, and progress |
| Release readiness gaps | `docs/roadmap/release-readiness.md` | Outstanding release prerequisites and closure evidence |
| Release readiness evidence | `docs/roadmap/release-readiness.md` | Closed preparation gaps and outstanding candidate/publication evidence until roadmap retirement |
| Historical release notes | `docs/releases/` | Version-specific historical summaries required by release policy |
| Complete examples | `examples/` and executable Go examples | Maintained artifacts; prose links instead of duplicating full examples |
A listed future owner is not a requirement to create an empty file now. Create
API, consumer, example, and component documents when the corresponding behavior
A listed owner is not a requirement to create an empty file before it has useful
content. Create API, consumer, example, and component documents when the corresponding behavior
exists and there is useful content to own. Link only to existing files; use plain
code paths for planned files. Release prerequisites have the explicit temporary
exception recorded in the release policy.
code paths for planned files. Unvalidated candidate and publication work has the
explicit temporary exception recorded in the release policy.
ConfigKit has no owned HTTP service, application CLI, or runtime operations
interface. Do not create those reference documents for consuming applications.

View File

@@ -222,17 +222,21 @@ restating or redefining its requirements.
### Temporary bootstrap deferral
The release procedure (`docs/release.md`) and complete release-check command are
not yet present because ConfigKit has no Go module or implementation to validate.
Their creation is temporarily deferred during initial development. This exception
permits implementation work; it does not permit publishing a release without
any gate required above.
The release procedure and automated source-candidate checker now exist, but no exact
release candidate, version-matched release note, native macOS execution evidence, or
post-publication module retrieval has been validated. Initial implementation may be
completed without fabricating those later facts. This exception does not authorize
publication or waive any candidate, platform, remote, or consumer-verification gate.
Compensating controls: no release may be published until the
[release-readiness gaps](../roadmap/release-readiness.md) are closed, the runbook
and checker exist, and the exact candidate passes all applicable gates. The
maintainer preparing the first release owns closure. Remove this temporary
exception when readiness is verified. Any other exception requires a documented repository constraint, rationale,
Compensating controls: the [release procedure](../release.md) keeps every unvalidated
step as an explicit maintainer gate, and the
[release-readiness evidence](../roadmap/release-readiness.md) records what is closed
and outstanding. No release may be published until an exact committed candidate has
the required release note, passes all applicable automated and native-platform gates,
is verified against `origin/main`, and completes guarded tag publication and clean
consumer retrieval. The maintainer preparing the first release owns closure. Remove
this temporary exception when that evidence is recorded and obsolete roadmap files
are retired. Any other exception requires a documented repository constraint, rationale,
compensating controls, scope, and closure condition here; none is currently
adopted. Do not silently weaken the base integrity, validation, documentation,
verification, or immutability guarantees.

View File

@@ -39,7 +39,7 @@ boundaries. No credential bytes may appear in inspection or failure fixtures'
expected output; use disposable canaries to prove non-disclosure.
Baseline commands belong in the [development guide](../development.md). Release
gates belong in the [release policy](release.md) and its eventual runbook. This
gates belong in the [release policy](release.md) and [maintainer runbook](../release.md). This
policy does not imply that those tools or tests already exist.
## Every test has a cost

240
docs/release.md Normal file
View File

@@ -0,0 +1,240 @@
# ConfigKit Release Procedure
This is the maintainer runbook for ConfigKit's [release policy](policy/release.md).
ConfigKit publishes one source-only Go module: the immutable source tag and the
matching checked-in release note are the deliverables. There is no application
binary, container image, generated package, or separate registry publication.
## Release identity and support
- Module: `gitea.maximumdirect.net/eric/ConfigKit`
- Primary branch: `main`
- Authoritative remote: `origin`, expected to fetch from
`https://gitea.maximumdirect.net/eric/ConfigKit.git`
- Tags: stable Semantic Versions such as `v0.1.0`; prerelease tags are not supported
- Minimum Go language/toolchain line: Go 1.25, tested with a supported patched
Go 1.25 toolchain and one newer supported toolchain
- Build targets: Linux and macOS on amd64 and arm64
The automated checker cross-builds all four targets. Before release, the maintainer
must also obtain native test, race, symlink, and permission-fixture evidence on Linux
and macOS; cross-compilation is not native execution evidence.
## 1. Prepare access and tools
The release maintainer owns this procedure. Work in a dedicated clone with Git, Bash,
and two supported Go toolchains available. Configure private-host Git and Go module
access through the normal credential manager before starting. Keep tokens, passwords,
SSH material, and environment dumps outside the repository and command transcript.
Verify access without displaying credentials:
```sh
git remote get-url origin
git ls-remote origin HEAD
```
The remote URL must equal the authoritative URL above. Select the latest supported
patch in the Go 1.25 line and a newer supported toolchain. The values below are the
toolchains used while this runbook was introduced; update them to supported patch
releases during candidate preparation and record the actual versions in the release
note or validation record.
```sh
export CONFIGKIT_BASELINE_TOOLCHAIN=go1.25.5
export CONFIGKIT_NEWER_TOOLCHAIN=go1.26.7
GOTOOLCHAIN="$CONFIGKIT_BASELINE_TOOLCHAIN" go version
GOTOOLCHAIN="$CONFIGKIT_NEWER_TOOLCHAIN" go version
GOTOOLCHAIN="$CONFIGKIT_BASELINE_TOOLCHAIN" go mod download
GOTOOLCHAIN="$CONFIGKIT_NEWER_TOOLCHAIN" go mod download
```
Those commands explicitly acquire toolchains and dependencies. The checker itself
sets `GOPROXY=off` and fails if its required cache is incomplete.
## 2. Select the version and review compatibility
Choose an unused stable version and compare the candidate with the previous tag.
For the first release, review the whole public surface and current contracts.
```sh
release_version=v0.1.0
printf '%s\n' "$release_version" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'
git show-ref --verify --quiet "refs/tags/$release_version" && exit 1 || :
if git ls-remote --exit-code --tags origin "refs/tags/$release_version" >/dev/null; then
printf 'remote tag already exists: %s\n' "$release_version" >&2
exit 1
else
test $? -eq 2
fi
git log --oneline --decorate --no-merges
```
Review exported Go signatures and ownership, YAML and scalar behavior, precedence,
diagnostic codes, minimum Go version, and platform support. Before `v1.0.0`, any
intentional incompatible minor-release change must be explained with consumer action;
patch releases must remain compatible within their minor line. Review the maintained
consumer examples and the migration guide even when signatures did not change.
Reassess `go.yaml.in/yaml/v4` rather than using `@latest` implicitly:
```sh
go list -m -versions go.yaml.in/yaml/v4
go list -m -json go.yaml.in/yaml/v4@latest
```
If changing the explicit pin, make that a reviewed dependency change and rerun the
complete checker, especially parser policy, limits, diagnostics, and rendering tests.
If retaining a prerelease pin, record that decision in Compatibility.
## 3. Write the release note
Create `docs/releases/$release_version.md` before selecting the candidate. It must
begin with `# ConfigKit $release_version` and contain `Summary`, `Compatibility`,
`Upgrade`, and `Changes` sections. Use “No action required” where appropriate. Link
to current canonical contracts instead of copying their definitions. Do not create a
release note until there is a real candidate and reviewed content.
## 4. Validate the source candidate
Run the complete checker from the repository root after dependencies have been
acquired. It validates module manifests in a disposable copy, both supported Go
toolchains, offline default tests, the native race detector, vet, native builds,
CGO-disabled cross-builds, formatting and whitespace (including untracked files),
examples, package isolation, and local documentation links.
```sh
./scripts/release-check.sh
```
`go vet` is the repository's static-analysis baseline. No additional linter is
claimed. Links to current ConfigKit files and headings are strict. Recorded links to
sibling consumer source are checked when those checkouts exist and are otherwise
inapplicable in an isolated clone; their immutable revisions remain recorded in the
extraction inventory.
Complete these manual gates and record their evidence with the candidate:
- The maintainer reviews compatibility and downstream migration impact against
`docs/config.md`, Go API comments, and the consumer guide.
- The maintainer inspects `git status --short`, `git diff`, and the candidate file
list for credentials, private data, generated output, unintended files, and
unrelated changes.
- The maintainer records successful native checker runs on Linux and macOS, including
filesystem capability tests. If either host is unavailable, release remains
blocked unless platform support is formally narrowed in current documentation.
- The maintainer removes completed, obsolete documents under `docs/roadmap/`, repairs
inbound links, and reruns the checker. ADR rationale remains historical.
- The maintainer reviews the exact version-matched release note for accuracy and
confirms it describes only deliverables that will actually be published.
## 5. Commit, push, and record the candidate
Commit all candidate source, contract, example, roadmap-retirement, and release-note
changes, rerun the checker against that clean commit, then push only `main` and record
the exact commit in Git metadata local to the clone:
```sh
git add .
git commit --message "Prepare ConfigKit $release_version"
./scripts/release-check.sh
test -z "$(git status --porcelain=v1 --untracked-files=all)"
git push origin HEAD:refs/heads/main
git rev-parse HEAD | tee .git/configkit-release-candidate
candidate_commit=$(cat .git/configkit-release-candidate)
```
If review changes the source after this point, create and validate a new candidate;
do not reuse the recorded commit.
## 6. Run publication guards
Immediately before tagging, fetch the authoritative branch and tags, restore the
recorded variables if this is a new shell, and execute every guard:
```sh
release_version=v0.1.0
candidate_commit=$(cat .git/configkit-release-candidate)
git fetch --prune origin main
git fetch --tags origin
test "$(git branch --show-current)" = main
test -z "$(git status --porcelain=v1 --untracked-files=all)"
test "$(git rev-parse HEAD)" = "$candidate_commit"
test "$(git rev-parse refs/remotes/origin/main)" = "$candidate_commit"
test "$(git remote get-url origin)" = 'https://gitea.maximumdirect.net/eric/ConfigKit.git'
printf '%s\n' "$release_version" | grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'
test -f "docs/releases/$release_version.md"
test "$(sed -n '1p' "docs/releases/$release_version.md")" = "# ConfigKit $release_version"
for heading in Summary Compatibility Upgrade Changes; do
grep -Fxq "## $heading" "docs/releases/$release_version.md"
done
git show-ref --verify --quiet "refs/tags/$release_version" && exit 1 || :
if git ls-remote --exit-code --tags origin "refs/tags/$release_version" >/dev/null; then
printf 'remote tag already exists: %s\n' "$release_version" >&2
exit 1
else
test $? -eq 2
fi
```
Confirm the recorded automated and manual approvals apply to exactly
`$candidate_commit`. A successful older run is not evidence for a changed commit.
## 7. Tag and publish the exact ref
Create one annotated tag at the guarded commit, verify its peeled target, and push
only that ref. Do not use `git push --tags`.
```sh
git tag --annotate "$release_version" --message "ConfigKit $release_version" "$candidate_commit"
test "$(git rev-list -n 1 "$release_version")" = "$candidate_commit"
git push origin "refs/tags/$release_version:refs/tags/$release_version"
```
The pushed tag completes the declared source-only publication. No Gitea release
object or binary upload is required.
## 8. Verify publication and clean consumer retrieval
Verify the authoritative tag and then retrieve that exact version into a new module
without a local `replace` directive. Private-host credentials must already be
configured. Use direct origin retrieval unless an explicitly approved internal Go
proxy is the publication channel.
```sh
remote_tag_commit=$(git ls-remote origin "refs/tags/$release_version^{}" | awk '{print $1}')
test "$remote_tag_commit" = "$candidate_commit"
consumer_dir=$(mktemp -d)
(
cd "$consumer_dir"
go mod init example.invalid/configkit-release-check
GOPRIVATE=gitea.maximumdirect.net GOPROXY=direct go get "gitea.maximumdirect.net/eric/ConfigKit@$release_version"
cat > main.go <<'EOF'
package main
import configkit "gitea.maximumdirect.net/eric/ConfigKit"
func main() {
_ = configkit.NoSource()
}
EOF
gofmt -w main.go
go test ./...
go build ./...
go list -m -f '{{.Path}} {{.Version}}' gitea.maximumdirect.net/eric/ConfigKit
)
rm -rf -- "$consumer_dir"
```
The final `go list` output must show the exact module path and `$release_version`.
Record the result with the release evidence.
## 9. Handle failures without replacement
Before publication, fix the candidate, rerun every gate, commit, push, and record a
new exact candidate. An unpublished local tag may be deleted only after verifying it
was never pushed or used by another release channel.
After publication, never move, delete, or recreate the tag and never replace its
release note. Correct the defect on `main`, choose a new semantically appropriate
version, and repeat this procedure. A supported advisory or deprecation mechanism
may warn consumers about the old version but cannot change its contents.

View File

@@ -2,8 +2,8 @@
## Status and ownership
Status: implementation in progress; Stages 1–15 are complete and later stages are
pending.
Status: implementation complete; Stages 1–22 are complete. Release-candidate
selection and publication remain separate maintainer work.
Audience: a `gpt-5.6-terra` coding agent implementing one stage per prompt, in
ascending order. Each stage depends on every earlier stage being complete.
@@ -85,7 +85,7 @@ the adapter, YAML-policy, diagnostics, limits, and rendering regressions. A fina
upstream version is preferred when it passes those checks; if the RC is retained,
record that decision in release readiness and compatibility review.
Follow the feature's [upstream isolation contract](initial.md#yaml-dependency-and-public-api-isolation).
Follow the feature's [upstream isolation contract](../policy/architecture.md#public-api-and-dependency-direction).
Translate upstream API changes internally without changing ConfigKit declarations
or consumer requirements. Never re-export upstream aliases/options/plugins, expose
parser errors through wrapping, or pass parser-created objects through `any`.
@@ -97,8 +97,8 @@ unverified upstream versions or add a selectable-parser framework.
### Updated extraction map
Use the source revisions and adaptation policies owned by the feature's
[foundation](initial.md#existing-implementation-foundation) and
[secret bootstrap](initial.md#secret-references-and-explicit-bootstrap) sections.
[foundation](../internal/extraction.md) and
[secret bootstrap](../config.md#typed-secret-references) sections.
Paths below are relative to the named sibling repository. Reinspect them in
Stage 1 and record the exact revision actually copied. The maintainer is the sole
author of the relevant application code and has authorized its reuse and relicensing
@@ -154,9 +154,9 @@ syscall-level confinement, path discovery, or a public filesystem-provider API.
### Secret, override, and history implementation bounds
Follow the feature contracts for [secrets](initial.md#secret-references-and-explicit-bootstrap),
[CLI overrides](initial.md#cli-overrides), and
[explanation](initial.md#historical-value-explanation). Introduce these public APIs
Follow the feature contracts for [secrets](../config.md#typed-secret-references),
[CLI overrides](../config.md#explicit-cli-overrides), and
[explanation](../config.md#historical-value-explanation). Introduce these public APIs
only in Stages 16–19. Earlier stages cover ordinary types and file/profile layers;
they must not expose an unresolved secret as a completed load or silently accept
an override option. Extend the shared descriptor/projection graph for `Secret`
@@ -303,8 +303,8 @@ Completion evidence (2026-09-06):
No deviations were required. Paths, diagnostics, parsing, and all later behavior
remain assigned to subsequent stages.
Read: feature [foundation](initial.md#existing-implementation-foundation),
[consumer fit](initial.md#consumer-fit-and-intentional-migrations), all policies.
Read: feature [foundation](../internal/extraction.md),
[consumer fit](../consumers/README.md), all policies.
Tasks:
@@ -353,8 +353,8 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
metadata population and configuration lifecycle behavior remain later work.
Read: feature [paths](initial.md#paths-and-presence),
[diagnostics](initial.md#provenance-diagnostics-and-redaction), public metadata API.
Read: feature [paths](../config.md#layered-metadata),
[diagnostics](../config.md#safe-failures), public metadata API.
Tasks:
@@ -408,8 +408,8 @@ Completion evidence (2026-09-06):
`go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on linux/amd64. No
deviations were required; typed binding and decoding remain later work.
Read: feature [YAML policy](initial.md#yaml-and-scalar-policy),
[source constructors](initial.md#entry-point-and-reusable-application-definition).
Read: feature [YAML policy](../config.md#yaml-documents),
[source constructors](../config.md#single-source-loading).
Start with the extraction map's parser and strict-loader cases; the old
second-document acceptance defect is already fixed in Narratio.
@@ -485,8 +485,8 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
typed value operations remain later work.
Read: feature [typed decoding](initial.md#typed-decoding) and
[type/projection contract](initial.md#supported-types-and-projection).
Read: feature [typed decoding](../config.md#defaults-and-typed-decoding) and
[type/projection contract](../config.md#application-schema-binding).
Tasks:
@@ -537,8 +537,8 @@ Completion evidence (2026-09-06):
Go 1.26.7 on linux/amd64. No deviations were required; defaults and typed decoding
remain later work.
Read: feature [ownership](initial.md#recorded-resolution-and-validation) and
[type/projection contract](initial.md#supported-types-and-projection).
Read: feature [ownership](../config.md#recorded-application-resolution) and
[type/projection contract](../config.md#application-schema-binding).
Tasks:
@@ -590,7 +590,7 @@ Completion evidence (2026-09-06):
and `git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
public loading and schema-version checks remain later work.
Read: feature [defaults/null](initial.md#static-defaults-and-null) and typed decoding.
Read: feature [defaults/null](../config.md#defaults-and-typed-decoding) and typed decoding.
Tasks:
@@ -651,9 +651,9 @@ Completion evidence (2026-09-06):
`go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on linux/amd64. No
deviations were required; resolution and semantic validation remain later work.
Read: feature [lifecycle](initial.md#resolution-lifecycle),
[version hook](initial.md#schema-checking-and-secret-classification),
[results](initial.md#results-errors-and-inspection).
Read: feature [lifecycle](../config.md#single-source-loading),
[version hook](../config.md#application-schema-binding),
[results](../config.md#safe-failures).
Tasks:
@@ -715,7 +715,7 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
semantic validation remains later work.
Read: feature [resolution callbacks](initial.md#resolution-and-validation-callbacks).
Read: feature [resolution callbacks](../config.md#recorded-application-resolution).
Tasks:
@@ -776,8 +776,8 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
imports and profiles remain deliberately unavailable.
Read: feature [diagnostic callbacks](initial.md#resolution-and-validation-callbacks)
and [schema reports](initial.md#schema-checking-and-secret-classification).
Read: feature [diagnostic callbacks](../config.md#recorded-application-resolution)
and [schema reports](../config.md#application-schema-binding).
Tasks:
@@ -824,7 +824,7 @@ Completion evidence (2026-09-06):
[current composition contract](../config.md#strict-document-composition) owns the
implemented semantics; public import wiring remains deferred to subsequent work.
Read: feature [composition table](initial.md#composition-and-overlay).
Read: feature [composition table](../config.md#strict-document-composition).
Extract Narratio's additive composer and conflict tests before writing equivalent
code. Change empty-map expectations to the feature table and retain exact locations.
@@ -883,7 +883,7 @@ Completion evidence (2026-09-06):
`go test -race ./...`, `go vet ./...`, `go build ./...`, `go mod tidy -diff`, and
`git diff --check` with Go 1.26.7 on linux/amd64.
Read: feature [import graph](initial.md#explicit-imports-and-source-identity).
Read: feature [import graph](../config.md#explicit-imports).
Extract the flat import loader and tests, then generalize its graph, identity and
containment rules. Do not treat its root-only declarations as ConfigKit's contract.
@@ -1008,7 +1008,7 @@ Completion evidence (2026-09-06):
Verified `go test ./...`, `go test -race ./...`, `go vet ./...`, `go build ./...`,
and `git diff --check` with Go 1.26.7 on linux/amd64.
Read: feature [profiles](initial.md#profiles), composition/overlay table.
Read: feature [profiles](../config.md#selected-profiles), composition/overlay table.
Extract Narratio's overlay mechanics and profile tests; preserve the intentional
null/kind and profile-selection differences listed in the feature roadmap.
@@ -1064,8 +1064,8 @@ Completion evidence (2026-09-06):
Verified `go test ./...`, `go test -race ./...`, `go vet ./...`, `go build ./...`,
`go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on linux/amd64.
Read: feature [presence](initial.md#paths-and-presence),
[history](initial.md#provenance-diagnostics-and-redaction), metadata API.
Read: feature [presence](../config.md#layered-metadata),
[history](../config.md#safe-failures), metadata API.
Use Narratio's effective ownership and inspection tests as extraction evidence.
Its source-only records need locations and complete historical operations.
@@ -1123,8 +1123,8 @@ Completion evidence (2026-09-06):
`go build ./...`, `go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on
linux/amd64.
Read: feature [redaction](initial.md#provenance-diagnostics-and-redaction),
[secret predicate](initial.md#schema-checking-and-secret-classification), result API.
Read: feature [redaction](../config.md#safe-failures),
[secret predicate](../config.md#application-schema-binding), result API.
Reuse Narratio's deterministic effective-output and non-disclosure cases. Render
from the owned typed projection, without its marshal/parse reconstruction.
@@ -1195,7 +1195,7 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
environment-backed typed secret references remain later work.
Read: [secret bootstrap contract](initial.md#secret-references-and-explicit-bootstrap),
Read: [secret bootstrap contract](../config.md#typed-secret-references),
architecture responsibility boundary, testing policy, and WeatherReporter's
`internal/config/secrets.go` and corresponding `config_test.go` cases; also
Narratio's `internal/app/secrets_env.go`, its tests, and bounded-read helper.
@@ -1267,7 +1267,7 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
CLI overrides remain later work.
Read: [secret reference contract](initial.md#secret-references-and-explicit-bootstrap),
Read: [secret reference contract](../config.md#typed-secret-references),
shared descriptor/projection rules and lifecycle, Stage 16 report boundary.
Tasks:
@@ -1337,7 +1337,7 @@ Completion evidence (2026-09-06):
`git diff --check` with Go 1.26.7 on linux/amd64. No deviations were required;
safe historical-value explanation remains later work.
Read: [override contract](initial.md#cli-overrides), overlay/presence/version rules,
Read: [override contract](../config.md#explicit-cli-overrides), overlay/presence/version rules,
source ordering, and the secret-reference boundary.
Tasks:
@@ -1403,7 +1403,7 @@ Completion evidence (2026-09-06):
`go build ./...`, `go mod tidy -diff`, and `git diff --check` with Go 1.26.7 on
linux/amd64. No deviations were required; consumer ergonomics remain later work.
Read: [explanation contract](initial.md#historical-value-explanation), redaction
Read: [explanation contract](../config.md#historical-value-explanation), redaction
rules, and history bounds above.
Generalize Narratio's semantic-record and inspection tests. They cover effective
@@ -1598,7 +1598,47 @@ Acceptance:
## Stage 22 — Prepare release validation and reconcile documentation
Status: pending.
Status: complete.
Completion evidence (2026-09-06):
- Added the [maintainer release procedure](../release.md) for the existing
`origin/main`, module `gitea.maximumdirect.net/eric/ConfigKit`, source-only stable
tags, Go 1.25 minimum and newer-toolchain validation, and Linux/macOS amd64/arm64
targets. It supplies candidate recording, clean branch/index/worktree and exact
remote-commit guards, version/release-note/tag checks, precise single-ref tag
publication, clean consumer retrieval without `replace`, and immutable correction
steps. Private-host access is a prerequisite without embedding credentials or
environment dumps.
- Added fail-fast [`scripts/release-check.sh`](../../scripts/release-check.sh). It
verifies cached dependencies and runs offline disposable-copy module hygiene,
default tests on Go 1.25.5 and Go 1.26.7, vet and native builds on both, a native
race run, CGO-disabled builds for linux/amd64, linux/arm64, darwin/amd64, and
darwin/arm64, repository-wide Go formatting and text whitespace including
untracked files, executable examples, consumer fixtures, public import isolation,
and local documentation links. Toolchain/dependency acquisition remains an
explicit preceding runbook step.
- Added `TestLocalDocumentationLinks`, which strictly verifies repository-local files
and Markdown headings while treating recorded sibling-source links as applicable
only when those optional checkouts exist. The runbook makes immutable extraction
revisions authoritative in isolated release clones.
- Reconciled README, development, configuration, consumer, architecture/testing/
documentation/release policies, component and extraction inventories, and ADR
navigation with current behavior. Reduced the implemented feature roadmap to a
target record linking current owners and retaining only foundations plus explicit
non-goals/deferred scope. The implementation plan and readiness record remain until
an actual candidate retires completed roadmap files as required by release policy.
- Reassessed the YAML v4 dependency with `go list -m -versions` and
`go list -m -json ...@latest`; `v4.0.0-rc.6` remained the newest available release
on 2026-09-06, so the tested explicit pin was retained. `go doc -all` and
`TestDependencyImportBoundary` confirmed public documentation is renderable and no
upstream YAML type/import leaks outside the private adapter or maintained examples.
- The complete checker passed on linux/amd64 with Go 1.25.5 and Go 1.26.7. The
[release-readiness evidence](release-readiness.md) keeps exact candidate/release
note, native macOS execution, compatibility/content approval, roadmap retirement,
authoritative remote/tag guards, and post-publication retrieval explicitly open
under the revised bootstrap exception. No tag, push, downstream migration, release
note, or publication occurred.
Read: release policy in full and [release-readiness gaps](release-readiness.md).

File diff suppressed because it is too large Load Diff

View File

@@ -2,24 +2,36 @@
## Status and ownership
ConfigKit is not release-ready. This document tracks outstanding release
prerequisites under the [temporary bootstrap exception](../policy/release.md#temporary-bootstrap-deferral).
It is not the library implementation plan and does not assign implementation
stages. The maintainer preparing the first release owns closure.
ConfigKit's implementation is prepared for release-candidate validation, but no
release candidate has been selected or publication authorized. The maintainer
preparing the first release owns the remaining gates under the
[temporary bootstrap exception](../policy/release.md#temporary-bootstrap-deferral).
This evidence record remains until candidate preparation retires completed roadmap
material in favor of the operational [release procedure](../release.md) and normal
release notes.
## Outstanding prerequisites
## Preparation evidence
| Gap | Evidence required to close |
| Preparation item | Status and evidence |
| --- | --- |
| No Go module or declared support matrix | Established module path, supported Go versions and platform targets documented in the release procedure |
| No release runbook | `docs/release.md` exists with the prerequisites, commands, publication guards, and verification required by release policy |
| No complete release checker | A documented command exists and exercises every applicable automated candidate gate; manual gates and inapplicable checks are explicit |
| No consumer verification procedure | Runbook verifies retrieval of the exact released module version and a representative consumer build without local replacement directives |
| No verified secret/precedence/explanation contracts | Current contracts and passing bootstrap skip/partial-failure, secret isolation, CLI precedence, and safe historical-value regressions; representative consumer examples |
| No validated release candidate | Version-matched release note, current contracts/examples, and complete checks against the exact committed candidate |
| Module and support matrix | Closed: the runbook records module `gitea.maximumdirect.net/eric/ConfigKit`, minimum Go 1.25 with a patched 1.25 plus newer supported toolchain, and Linux/macOS on amd64/arm64. |
| Maintainer release procedure | Closed: `docs/release.md` owns access prerequisites, candidate recording, complete validation, exact remote/commit/tag guards, source-only publication, consumer retrieval, and correction. |
| Automated source checker | Closed for current-source preparation: `scripts/release-check.sh` passed on 2026-09-06 with Go 1.25.5 and Go 1.26.7 on linux/amd64. It performs disposable-copy module hygiene, cached/offline tests, race, vet, native and four-target cross-builds, formatting/whitespace, examples, import isolation, and local-link gates. The exact candidate must rerun it. |
| Consumer verification procedure | Closed as procedure: the runbook retrieves an exact published version into a clean temporary module with no local replacement and tests/builds it. Actual retrieval remains a post-publication gate. |
| Secret/precedence/explanation evidence | Closed locally: current contracts and deterministic tests cover bootstrap skip/partial failure, credential isolation, defaults/base/profile/CLI precedence, historical redaction, and maintained consumer startup examples. |
| Parser dependency reassessment | Closed for preparation: on 2026-09-06, `go list -m -versions go.yaml.in/yaml/v4` and `go list -m -json go.yaml.in/yaml/v4@latest` both showed `v4.0.0-rc.6` as the newest available release. The explicit pin is retained; a candidate compatibility review must reassess and record it again. |
No release can proceed while these prerequisites remain open. Close items only
on evidence from actual files and checks, not proposed commands. Record closure
evidence here while this roadmap remains active. Once all gaps are closed,
remove the bootstrap exception and retire this document in favor of the
operational runbook and normal release records.
## Outstanding release gates
| Gate | Owner and closure evidence |
| --- | --- |
| Exact candidate and release note | Maintainer selects an unused stable version, writes `docs/releases/<version>.md`, commits all release changes, runs the checker against that exact clean commit, pushes it to `origin/main`, and records the commit. |
| Native platform execution | Maintainer records applicable checker, race, symlink, and permission-fixture results on native Linux and macOS. Current local evidence is Linux/amd64 only; cross-builds do not close macOS execution. |
| Compatibility, migration, and content review | Maintainer records public API/configuration/diagnostic review, downstream migration impact, release-note approval, and inspection for credentials, private data, generated output, unintended files, and unrelated changes. |
| Roadmap retirement | Maintainer removes obsolete completed files under `docs/roadmap/`, repairs inbound links, and reruns the checker as part of the candidate. This record and the implementation plan intentionally remain while no candidate exists. |
| Remote publication guards | Maintainer fetches authoritative `origin/main` and tags immediately before publication and proves branch, clean worktree/index, candidate commit, remote commit, release note, approvals, and unused version all agree. |
| Tag and retrieval verification | After authorization, maintainer pushes only the exact immutable source tag, verifies its peeled remote commit, and retrieves/tests/builds the exact version in a clean consumer module without `replace`. |
No tag, push, downstream migration, release note, or release publication was
performed during implementation. A green local checker does not close the exact
candidate, native macOS, remote, or post-publication gates.