diff --git a/docs/adr/README.md b/docs/adr/README.md index e9210fe..50da111 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -1,6 +1,11 @@ # Architectural Decision Records -No ADRs have been recorded here. Use the +## Accepted + +- [ADR 0001: Adopt ReleaseKit for release management](0001-releasekit.md) — + accepted 2026-10-07. + +Use the [documentation policy's ADR lifecycle](../policy/documentation.md#architecture-decision-records) for significant decisions. Current architecture belongs in the [architecture policy](../policy/architecture.md); implementation status belongs in diff --git a/docs/cli.md b/docs/cli.md index dc5bc90..de8d160 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -11,6 +11,7 @@ the [migration guide](migrations/v2.md) maps retired inputs. audita process --glossary [flags] audita config validate --config [flags] audita config print-effective [flags] +audita version ``` Root invocation, `--help`, `-h`, and command help succeed without loading a config @@ -26,6 +27,15 @@ Missing system candidates are skipped; inaccessible selected files are errors. No file means a configuration error. `AUDITA_CONFIG` is ignored. The selected overlay is loaded beside the main file, not used to locate profile files. +`audita version` prints `audita ` and a newline to stdout, with no +application configuration or provider setup. It returns `0` on success with +empty stderr. `help version`, `version -h`, and `version --help` print command +usage to stdout and return `0`; unexpected arguments and unknown flags return +`2` with a usage error on stderr. The command uses ReleaseKit's public +`buildinfo.Version()` accessor. It reports an injected release identifier when +present, otherwise the executable's main-module version when available and not +`(devel)`, and `dev` when neither source provides a release identifier. + ## Setting overrides Only flags actually supplied override file or overlay settings. `--modules ''` diff --git a/docs/internal/cli-config.md b/docs/internal/cli-config.md index 66cb1fb..daa246a 100644 --- a/docs/internal/cli-config.md +++ b/docs/internal/cli-config.md @@ -27,6 +27,11 @@ CLI wiring, and maintained examples. Definitions of behavior belong to the for the changed behavior. 4. Update the CLI reference and affected integration guidance. +The `version` route uses ReleaseKit's public `buildinfo.Version()` accessor and +stays independent of application runtime assembly. Preserve its behavior from +the [CLI contract](../cli.md#commands-and-help) when changing the command; the +adoption decision is recorded in [ADR 0001](../adr/0001-releasekit.md). + ## Validating Examples Keep complete copyable files in [examples](../../examples/) and link to them from diff --git a/docs/oss/attribution.md b/docs/oss/attribution.md index 2bbb1c6..ead9b83 100644 --- a/docs/oss/attribution.md +++ b/docs/oss/attribution.md @@ -28,6 +28,20 @@ License and notices: [LGPL v3](licenses/LGPL-3.0.txt) | [Source](https://gitea.maximumdirect.net/eric/ConfigKit/src/commit/dc09959cca4e105f49ec316c6d4ba585bd2340bd). +## ReleaseKit + +Selected module: `gitea.maximumdirect.net/eric/ReleaseKit` at `v0.1.0`. + +Copyright (C) 2026 Eric Rakestraw + +SPDX-License-Identifier: LGPL-3.0-or-later + +License and notices: [LGPL v3](licenses/LGPL-3.0.txt) | +[GPL v3](licenses/GPL-3.0.txt) | +[COPYRIGHT](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1/COPYRIGHT). + +[Source](https://gitea.maximumdirect.net/eric/ReleaseKit/src/commit/5e60fe3113c69f95c42fbbe32a8ca4b51f5b83c1). + ## Go runtime and standard library Selected toolchain: Go 1.25.5 for the distributed Linux binaries. diff --git a/docs/policy/release.md b/docs/policy/release.md index 4ac5fc7..f6aa5e1 100644 --- a/docs/policy/release.md +++ b/docs/policy/release.md @@ -2,7 +2,7 @@ **Base Policy Version:** 1.4 -**Last Updated**: 2026-09-28 +**Last Updated**: 2026-10-07 **Upstream Source:** [Standard Repository Policies release](https://gitea.maximumdirect.net/eric/policy/src/commit/d84a38ebab26f048cafbe59a2246700c35d29843/docs/policy/release.md) ## Purpose @@ -49,12 +49,17 @@ failures and optional investigations under artifact-delivery status. | --- | --- | | Linux amd64 | Required production target | | Linux arm64 | Required production target | -| macOS arm64 | Best effort for local development; failures do not block a release or Linux artifact publication | +| macOS arm64 | Best effort for local development; development failures do not block a release or Linux artifact publication | Windows and macOS amd64 are unsupported. Neither their builds nor tests are release requirements. Native macOS testing and access to a Mac are not release prerequisites. +Linux amd64 and arm64 remain the required production targets. Publication from +a host outside the selected target set must pass ReleaseKit's temporary native +version check. This check does not require access to a Mac or native tests on +every delivery target. + ## Versioning And Compatibility Stable releases use Semantic Versioning in the form `vMAJOR.MINOR.PATCH`, with diff --git a/docs/release.md b/docs/release.md index c5699e3..e0130bd 100644 --- a/docs/release.md +++ b/docs/release.md @@ -1,144 +1,120 @@ # Releasing Audita -The [release policy](policy/release.md) defines versioning, supported platforms, -immutability, and success. This runbook implements it with -[scripts/release.sh](../scripts/release.sh). Publication ends after a successful -source/tag push; binary delivery runs asynchronously. +The [release policy](policy/release.md) owns release requirements. This runbook +uses the native commands in [scripts/release.sh](../scripts/release.sh), which +builds and invokes ReleaseKit. A confirmed source tag completes the release; +Woodpecker reports binary delivery separately. ## Prerequisites -Use Bash, Git, and Go 1.25.5 or newer (CI uses Go 1.25.5), with dependencies -available locally or downloadable. Tests themselves are offline. Work from a -checkout of `main` with permission to push that branch and tags to `origin`. -For this repository, `origin` is `https://gitea.maximumdirect.net/eric/audita.git`. -The script uses the checkout's configured `origin`; set it correctly before use. -The remote must support atomic pushes. No CI credentials or Mac are needed locally. +Use Bash, Git, and Go 1.25.5 or newer. The authoritative remote is `origin`, +which must point to `https://gitea.maximumdirect.net/eric/audita.git`; the +primary branch is `main`. Source publication needs no delivery credential. +Woodpecker uses the existing `GITEA_RELEASE_TOKEN` secret for delivery. -CI uses the existing `GITEA_RELEASE_TOKEN` secret for asynchronous asset delivery. -macOS arm64 is a best-effort development environment; no macOS binary is published. +Prepare dependencies before offline candidate validation: -## Prepare the Candidate +```sh +GOWORK=off GOTOOLCHAIN=local go mod download +``` -Choose an unused version following the policy. Write -`docs/releases/.md`, beginning with `# Audita `, followed by a -short summary and any compatibility or upgrade instructions relevant to the -release. There are no mandatory boilerplate sections. Update affected canonical -documentation with behavior changes. +If dependency preparation changes `go.mod` or `go.sum`, include those changes in +the committed candidate. The release wrapper separately bootstraps the pinned +ReleaseKit command into ignored `bin/releasekit`; that build is tool preparation, +not candidate validation. -End each new note with these links, substituting the selected release version for -``: +## Prepare and publish the candidate + +Choose an unused version under the [release policy](policy/release.md), write +`docs/releases/.md`, and begin it with `# Audita `. Include a +short summary, relevant compatibility or upgrade instructions, and the required +`COPYRIGHT | LICENSE | ATTRIBUTION` footer with links for the selected version. +Update affected canonical documentation with behavior changes. + +End each note with this footer, substituting its complete tag for ``: ```markdown [COPYRIGHT](https://gitea.maximumdirect.net/eric/audita/src/tag//COPYRIGHT) | [LICENSE](https://gitea.maximumdirect.net/eric/audita/src/tag//LICENSE) | [ATTRIBUTION](https://gitea.maximumdirect.net/eric/audita/src/tag//docs/oss/attribution.md) ``` -Check that all three paths exist in the candidate source. Retire completed -roadmaps when useful during preparation, preserving planned and deferred work -and repairing affected links. This is ordinary preparation, not a script gate. - -Commit the intended changes, including the note, on `main`. The release script -requires a clean index and worktree and does not create commits. There is no -separate approval round. Published notes describe their tagged release; existing -release history does not need to be reconstructed. - -## Validate and Publish - -From the repository root, substitute the chosen version: +Commit the complete candidate on `main`, including the release note, then push +the branch first: ```sh -bash scripts/release.sh --publish v0.2.0 +git push origin main ``` -This single invocation: +Record the candidate commit. Before publication, remote `main` must identify +that exact commit. ReleaseKit checks this along with the clean candidate, note, +version, and remote tag state. -1. Checks the version, branch, clean candidate, matching note title, and tag absence. -2. Runs the default offline test suite once, then builds both required Linux targets - in a temporary directory using the same build script as CI. -3. Checks that the candidate and worktree are unchanged and that it includes the - current `origin/main` history. -4. Creates the version tag at that commit and atomically pushes the exact source - commit to `main` and the exact tag to `origin`. -5. Reports release success and exits without polling CI or checking asset availability. - -To validate a prepared candidate without remote access, creating a tag, or pushing: +Publish from the repository root, substituting the selected version: ```sh -bash scripts/release.sh --check v0.2.0 +bash scripts/release.sh publish VERSION ``` -This is an optional diagnostic command, not a required step before `--publish`. -Publication validates within its own invocation; it does not use persistent cached -results. Both modes require the candidate note and a clean `main` checkout. +The command runs `go test -mod=readonly -count=1 ./...` once with module and +toolchain network access disabled, builds the profile's Linux amd64 and arm64 +targets, and checks the native version output. It creates an annotated tag whose +message comes from the committed note, then pushes the exact tag object. A +successful publication completes the source release without waiting for CI or +checking artifact availability. -## Artifact Delivery +`bash scripts/release.sh check VERSION` is an optional local diagnostic. It +does not inspect remote availability or publish a tag, and it is not a required +step before `publish`, which performs its own candidate validation. -[Woodpecker](../.woodpecker/release.yml) runs on tag events. It invokes -[scripts/build-release.sh](../scripts/build-release.sh), then publishes: +The wrapper preserves ReleaseKit's exit status: `0` means confirmed publication; +`1` means a known validation or publication failure/conflict; `2` means usage, +profile, or version input error; and `3` means the push outcome remains unknown. + +## Binary delivery + +Woodpecker runs the pinned ReleaseKit `ci-deliver` command for tags under +`refs/tags/v*`. It verifies the triggering commit against the tag, prepares the +tagged source, and uses `releasekit.json` to build and deliver: - `audita--linux-amd64` - `audita--linux-arm64` - `SHA256SUMS` -Builds disable CGO and use the shared script's release flags. The version is in the -asset name and source tag; Audita has no CLI version command. Cross-compilation -checks compilation, not native execution on each architecture. - -The CI job status and logs show delivery progress or failure. Assets appear on -the matching Gitea release page when delivery succeeds. A successful tag push -must not be reported as confirmation that these files are available. -For a new hosted release, the release plugin uses the checked-in note at the -tag as its body, including the footer. On delivery retries it preserves -existing release information and skips files that already exist. - -Consumers can download the binary for their Linux architecture and `SHA256SUMS` -from that page, check its listed SHA-256 digest with `sha256sum`, and make it -executable. Optional consumer checks are not maintainer release gates. Digests -detect file mismatches; they are not an independent signature of authenticity. - -## Failure and Retry - -**Local validation fails:** correct the issue, commit any changes, and rerun the -publication command. A failure before tag creation publishes nothing. Temporary -local build files are removed on exit. - -**Push fails or the connection is interrupted:** the script retains the local tag -and reports failure rather than guessing whether publication succeeded. Inspect -remote state with the actual version: +The workflow invokes: ```sh -git rev-parse 'v0.2.0^{commit}' -git ls-remote origin refs/heads/main refs/tags/v0.2.0 +go run gitea.maximumdirect.net/eric/ReleaseKit/cmd/releasekit@${RELEASEKIT_VERSION} ci-deliver \ + --repo "$${CI_WORKSPACE}" \ + --commit "$${CI_COMMIT_SHA}" \ + "$${CI_COMMIT_TAG}" ``` -If the remote tag identifies the intended candidate and its source is on remote -`main`, the release succeeded; no CI waiting is needed. An atomic push normally -updates both refs or neither. If `main` has advanced since publication, fetch it -and check candidate ancestry rather than requiring tip equality. +Woodpecker sets `RELEASEKIT_VERSION` to `v0.1.0` for this workflow. -If the tag is absent remotely and was never published or used by a release -channel, remove only that unpublished local tag (`git tag -d v0.2.0`), resolve -any rejected branch update, and rerun the command. If the remote tag has a -different target, do not overwrite it; choose a fresh version. Never force a -branch or tag update to bypass the guards. +The complete checked-in release note, including its licensing footer, supplies +the hosted release body. The workflow maps the existing `GITEA_RELEASE_TOKEN` +secret to `RELEASEKIT_GITEA_TOKEN`. Delivery runs independently after source +publication; its status and logs report delivery progress or failure. -**CI delivery fails:** the release remains successful. Inspect the failed tag -job's logs and retry that same tagged job for a transient failure. Publication is -configured to skip existing filenames and not overwrite assets. Keep the same -source and build environment when retrying; inspect any existing assets/checksum -manifest before filling gaps. Do not regenerate and replace a published manifest -or binary. If an existing manifest cannot describe the missing rebuilt assets, -use a new version instead. A pipeline or source defect also requires a corrected -commit and new version. An outage does not require moving the tag. +ReleaseKit handles content-aware retries and retained-artifact recovery. See +the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md) +and [delivery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md) +for those mechanics. A delivery failure does not undo a confirmed source +release. Retry the same immutable tag after resolving the reported state; do not +replace published files or a checksum manifest. -**A released source defect is discovered:** fix it on `main` and publish a new -appropriate version with a note explaining the correction. Leave the old tag and -published files intact. +## Failure and recovery -## Maintaining the Release Workflow +Fix validation failures in a new committed candidate, then rerun `publish`. +After a failed push, ReleaseKit retains the local annotated tag and reports the +captured authoritative endpoint and publication state. Resolve the result +against that endpoint before retrying. An exact remote tag-object match, with +its source available on remote `main`, can confirm publication. If the remote +state cannot be read, the result remains unknown; do not remove or replace the +tag while uncertain. Follow the pinned [publication recovery guide](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/publish.md) +for object-level recovery details. -The shared build script keeps local and CI build settings aligned. Tests in -[scripts/release_test.go](../scripts/release_test.go) exercise publication against -temporary local Git remotes, including guard failures and rejected pushes, with -Go execution stubbed to avoid recursive builds/tests. They run in `go test ./...`. -Changes to CI delivery should preserve explicit asset names, checksums, and -non-overwriting publication. CI delivery is separate from the local success path. +A source-release success and artifact-delivery status are separate. For a +partial or uncertain delivery, inspect the job output and follow the pinned +[delivery recovery guidance](https://gitea.maximumdirect.net/eric/ReleaseKit/src/tag/v0.1.0/docs/consumers/delivery.md). +A source or published-content correction requires a new appropriate version; +leave the original tag and its contents intact. diff --git a/docs/roadmap/configkit.md b/docs/roadmap/configkit.md index c4900ed..fa3a92f 100644 --- a/docs/roadmap/configkit.md +++ b/docs/roadmap/configkit.md @@ -5,8 +5,8 @@ **Status:** Complete. The implementation and tests are committed through `8175ed8`. Final documentation and example changes were included in the full build, test, example-validation, and local-link checks before the documentation -completion commit. The [implementation plan](implementation.md) records the -ordered work and verification. +completion commit. The [historical implementation plan](https://gitea.maximumdirect.net/eric/audita/src/commit/b31955fc97adec707b4e5f9a1b0c43c4cbc66750/docs/roadmap/implementation.md) +records the ordered work and verification. ## Purpose and Baseline diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 1bd1d78..4dda5d5 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -1,7 +1,7 @@ # Implementation Plan: ReleaseKit Adoption **Last updated:** 2026-10-07 -**Status:** Stages 1–3 complete; Stages 4–5 pending. +**Status:** Stages 1–4 complete; Stage 5 pending. **Audience:** Luna coding agent. ## Scope and Execution @@ -203,9 +203,9 @@ is observed during subsequent delivery, independently of source completion. `ci-deliver` step using the existing secret, then removed the obsolete binary builder. Verified the parsed workflow settings and command against the pinned template, confirmed the module/workflow pins match, ran `go test ./scripts`, -checked for active builder references, and passed `git diff --check`. +confirmed no active CI or script caller remained, and passed `git diff --check`. -## Stage 4 — Align Policy, Documentation, and Attribution +## Stage 4 — Align Policy, Documentation, and Attribution [x] **Primary files:** `docs/release.md`, `docs/policy/release.md`, `docs/cli.md`, `docs/internal/cli-config.md`, `docs/adr/README.md`, and @@ -261,6 +261,12 @@ local links and anchors, pinned upstream references, source attribution, and `git diff --check`. Use the prior successful code checks for unchanged code. Commit the documentation unit. +**Completed 2026-10-07:** Updated the ReleaseKit runbook, release policy, +version contract and contributor guidance, ADR index, and component attribution. +Repaired PromptKit and ConfigKit links to their historical implementation +records. Verified local links and anchors, release CLI and version commands, +pinned module/notices, source attribution, and `git diff --check`. + ## Stage 5 — Verify Adoption and Close the Plan **Primary files:** This plan and the ReleaseKit feature roadmap; fix an diff --git a/docs/roadmap/promptkit.md b/docs/roadmap/promptkit.md index de4a126..0e0a497 100644 --- a/docs/roadmap/promptkit.md +++ b/docs/roadmap/promptkit.md @@ -262,8 +262,8 @@ No live provider calls, new release gates, or CI-success dependency are needed to establish adoption. Guided domain recovery and the other work recorded in [future.md](future.md) remain separate features. Do not expand this upgrade into new report formats, pipeline scheduling, or general configuration-inspection -commands. The [implementation plan](implementation.md) owns execution steps -and their verification. +commands. The [historical implementation plan](https://gitea.maximumdirect.net/eric/audita/src/commit/418da456d75a68d3bb5a43ab823c5b2b434b90cc/docs/roadmap/implementation.md) +records that work's execution steps and verification. ## Completion Record