diff --git a/.codebase-memory/artifact.json b/.codebase-memory/artifact.json index b72abad..e629706 100644 --- a/.codebase-memory/artifact.json +++ b/.codebase-memory/artifact.json @@ -1,11 +1,11 @@ { "schema_version": 2, - "commit": "7f46c947dd56f437077df475ba5bba8fd864e2e1", - "indexed_at": "2026-09-12T16:26:42Z", + "commit": "88e86de03ebd87038b0c98b164865f2c3b82a94c", + "indexed_at": "2026-09-12T18:30:58Z", "project": "home-eric-Workspace-ConfigKit", - "nodes": 1625, - "edges": 7824, + "nodes": 1641, + "edges": 7961, "original_size": 8126464, - "compressed_size": 1329933, + "compressed_size": 1350795, "compression_level": 3 } \ No newline at end of file diff --git a/.codebase-memory/graph.db.zst b/.codebase-memory/graph.db.zst index a70f3c4..99b8b8c 100644 Binary files a/.codebase-memory/graph.db.zst and b/.codebase-memory/graph.db.zst differ diff --git a/README.md b/README.md index fa5c1fc..4534195 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,9 @@ An opinionated Go library for applications that use YAML configuration files. +Linux is release-validated; macOS support is best-effort. See the +[platform support policy](docs/policy/release.md#platform-support) for details. + ConfigKit's initial loader accepts one strict YAML source (or explicit defaults-only input), optionally traverses explicit path and glob imports, strictly composes their disjoint definitions, applies typed defaults, and diff --git a/docs/policy/release.md b/docs/policy/release.md index 64fddf6..3e6ff52 100644 --- a/docs/policy/release.md +++ b/docs/policy/release.md @@ -2,7 +2,7 @@ **Base Policy Version:** 0.1.0 -**Last Updated:** 2026-09-07 +**Last Updated:** 2026-09-12 ## Purpose @@ -35,6 +35,20 @@ can still break consumers. Human diagnostic wording is stable only where a contract expressly promises it. Minimum Go version and platform support changes also require an explicit compatibility assessment. +### Platform support + +Linux is the release-validated platform. macOS has best-effort support: keeping +it working remains desirable, but neither native macOS validation nor Darwin +cross-builds are release gates. Missing macOS evidence or a macOS-specific failure +does not by itself block a release. Voluntary checks and fixes are welcome; there +is no guarantee that each release has been validated on macOS. + +The [release procedure](../release.md#release-identity-and-support) owns target +architectures and required Linux checks. This support change applies to upcoming +releases; historical release notes and their validation records remain unchanged. +The next release note must explain the change in Compatibility, with version +selection following this policy's existing compatibility rules. + ## Release Model A release consists of: diff --git a/docs/release.md b/docs/release.md index 7e3e380..a7ebc86 100644 --- a/docs/release.md +++ b/docs/release.md @@ -14,11 +14,14 @@ binary, container image, generated package, or separate registry publication. - 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 +- Release-gated build targets: Linux on amd64 and arm64 +- Best-effort targets: macOS on amd64 and arm64, under the + [platform support policy](policy/release.md#platform-support) -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. +The automated checker cross-builds the Linux targets. Before release, the maintainer +must also obtain native test, race, symlink, and permission-fixture evidence on Linux; +cross-compilation is not native execution evidence. Native macOS checks and Darwin +cross-builds are optional and do not gate publication. ## 1. Prepare access and tools @@ -97,10 +100,10 @@ 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 +Run the complete checker on Linux 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), +CGO-disabled Linux cross-builds, formatting and whitespace (including untracked files), examples, package isolation, and local documentation links. ```sh @@ -120,9 +123,9 @@ Complete these manual gates and record their evidence with the candidate: - 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 records a successful native checker run on Linux, including + filesystem capability tests. Missing required Linux evidence blocks release; + no macOS run, sign-off, or cross-build result is required. - 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 diff --git a/docs/roadmap/source-origins-during-resolution.md b/docs/roadmap/source-origins-during-resolution.md index ecbe684..92089ef 100644 --- a/docs/roadmap/source-origins-during-resolution.md +++ b/docs/roadmap/source-origins-during-resolution.md @@ -48,5 +48,5 @@ selected. Publication remains a maintainer decision. Release preparation must choose the version, write a version-matched note, retire this completed roadmap with link -repair, obtain exact-candidate Linux/macOS evidence, and follow the +repair, obtain the required exact-candidate Linux evidence, and follow the [release procedure](../release.md). diff --git a/release_check_test.go b/release_check_test.go index 3df41db..fc24ca9 100644 --- a/release_check_test.go +++ b/release_check_test.go @@ -47,7 +47,7 @@ func TestCheckScriptsHandleFilenamesAndStopOnFailure(t *testing.T) { } // Isolate expensive toolchain commands: this test owns shell orchestration, // not Go's compiler or the production tests exercised by the real checker. - write(filepath.Join(bin, "go"), []byte("#!/bin/sh\nprintf '%s\\n' \"$*\" >> \"$CONFIGKIT_TEST_GO_LOG\"\nif [ \"${CONFIGKIT_TEST_FAIL-}\" = yes ] && [ \"${1-}\" = test ]; then exit 37; fi\n"), 0700) + write(filepath.Join(bin, "go"), []byte("#!/bin/sh\nprintf '%s/%s %s\\n' \"${GOOS-native}\" \"${GOARCH-native}\" \"$*\" >> \"$CONFIGKIT_TEST_GO_LOG\"\nif [ \"${CONFIGKIT_TEST_FAIL-}\" = yes ] && [ \"${1-}\" = test ]; then exit 37; fi\n"), 0700) write(filepath.Join(bin, "gofmt"), []byte("#!/bin/sh\nprintf '%s\\000' \"$@\" > \"$CONFIGKIT_TEST_FMT_LOG\"\n"), 0700) init := exec.Command("git", "init", "-q") init.Dir = root @@ -67,6 +67,8 @@ func TestCheckScriptsHandleFilenamesAndStopOnFailure(t *testing.T) { } cmd := exec.Command("/bin/bash", filepath.Join(root, "scripts", scriptName)) cmd.Env = append(os.Environ(), "PATH="+bin+string(os.PathListSeparator)+os.Getenv("PATH"), "CONFIGKIT_BASELINE_TOOLCHAIN=test-baseline", "CONFIGKIT_NEWER_TOOLCHAIN=test-newer", "CONFIGKIT_TEST_FMT_LOG="+log, "CONFIGKIT_TEST_GO_LOG="+calls) + // Log only targets selected by the script, not inherited host settings. + cmd.Env = append(cmd.Env, "GOOS=", "GOARCH=") if name == "failed-go-check" { cmd.Env = append(cmd.Env, "CONFIGKIT_TEST_FAIL=yes") } @@ -101,6 +103,17 @@ func TestCheckScriptsHandleFilenamesAndStopOnFailure(t *testing.T) { if fail && strings.Contains(string(invoked), "vet ./...") { t.Fatal("checker continued after failed test") } + if scriptName == "release-check.sh" && !fail { + // These are selected release gates, not incidental loop details. + for _, target := range []string{"linux/amd64", "linux/arm64"} { + if !strings.Contains(string(invoked), target+" build ./...") { + t.Errorf("checker omitted required target %s", target) + } + } + if strings.Contains(string(invoked), "darwin/") { + t.Fatal("checker requires best-effort macOS validation") + } + } }) } }) diff --git a/scripts/release-check.sh b/scripts/release-check.sh index 07947ce..6c2c2ae 100755 --- a/scripts/release-check.sh +++ b/scripts/release-check.sh @@ -81,7 +81,8 @@ run_go "$newer_toolchain" test ./examples/consumers run_go "$newer_toolchain" test . -run '^TestLocalDocumentationLinks$' run_go "$newer_toolchain" test . -run '^TestDependencyImportBoundary$' -for target in linux/amd64 linux/arm64 darwin/amd64 darwin/arm64; do +# Only release-validated targets gate publication; macOS is best-effort. +for target in linux/amd64 linux/arm64; do target_os=${target%/*} target_arch=${target#*/} GOTOOLCHAIN="$newer_toolchain" GOPROXY=off CGO_ENABLED=0 GOOS="$target_os" GOARCH="$target_arch" go build ./...