Plan source-only releases

This commit is contained in:
2026-08-25 01:48:16 +00:00
parent 916532100d
commit a478fd86c5
3 changed files with 709 additions and 1 deletions

View File

@@ -153,7 +153,6 @@ section only after a concrete workflow, contract, and priority emerge.
### Distribution And Operations
- Packaged release artifacts for alpha distribution.
- A documented versioning and release process.
- Optional generated example-output fixtures with a regeneration procedure.
- Additional diagnostics or reporting views.

View File

@@ -0,0 +1,428 @@
# Source-Only Release Implementation Plan
## Purpose
Implement the target state defined by
[Source-Only Releases](source-releases.md): immutable source tags with checked-in
release notes, a diagnostic version interface, strong shared candidate checks,
validation-only tag CI, Linux support, best-effort macOS compilation, and no
packaged binaries or Windows support.
This plan is ordered. Each numbered stage is one implementation prompt for a
gpt-5.6-terra coding agent. Complete and validate one stage before beginning
the next. Preserve all unrelated worktree changes, follow every policy under
`docs/policy/`, and update current-behavior documentation in the same stage as
the behavior it describes.
Do not create or push a release tag while implementing this plan. Do not invent
a release note for `v0.1.0`, `v0.2.0`, or `v0.3.0`. The first real release
under the completed procedure will add its own note in a separate release
operation.
## Decisions Fixed For Implementation
- Releases are stable `vMAJOR.MINOR.PATCH` source tags on `main`; prereleases
are unsupported initially.
- Tags are lightweight and immutable after publication.
- No release binaries, archives, checksums, signatures, containers,
package-manager entries, or Gitea release objects are produced.
- Linux is supported. Release checks compile Linux `amd64` and `arm64` with
`CGO_ENABLED=0`.
- macOS is best-effort. Release checks compile Darwin `amd64` and `arm64` with
`CGO_ENABLED=0`, without promising runtime CI or packaged output.
- Windows is unsupported and must not be added to build checks.
- Release notes begin with the first release made under the new procedure;
historical tags are left untouched.
- `notarius --version` is informational. Receipt and artifact contracts remain
authoritative for downstream compatibility.
- One checked-in POSIX shell command owns substantive source-candidate checks.
The release procedure and tag CI call it rather than maintaining duplicate
test/build matrices.
- Tag CI validates only. Pre-publication local guards remain mandatory because
tag CI cannot prevent an already-pushed tag.
## Stage 1: Add Build Version Resolution And `--version`
### Goal
Add a small, testable build-information boundary and expose the public root
version flag without affecting existing command behavior.
### Implementation
1. Create `internal/buildinfo` with an exported link-time string variable named
`Override` and an exported resolver such as `Version() (string, error)`.
Keep this package independent of CLI and application packages.
2. Resolve the displayed value using this precedence:
1. a nonempty `Override`;
2. the main-module version returned by `runtime/debug.ReadBuildInfo`; then
3. the literal `development`.
3. Accept a release value only when it matches the complete stable SemVer tag
form `^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$`.
Whitespace, prerelease/build suffixes, pseudo-versions, and arbitrary text
are not release versions. A nonempty invalid linker override is an error;
an empty, `(devel)`, pseudo-version, or otherwise non-release main-module
version falls back to `development`.
4. Add `--version` to the root dispatch in `internal/cli`. It is valid only as
the sole argument, writes exactly `notarius <resolved-version>\n` to stdout,
writes nothing to stderr, and exits zero. Additional arguments are a syntax
error using the existing exit-2 and stderr conventions. An invalid linker
override is a runtime/build error using exit 1 and stderr.
5. Add the flag to root usage without changing the existing behavior of empty
arguments, help spellings, or subcommands.
6. Update `docs/cli.md` as the canonical public contract and
`docs/internal/cli.md` as the implementation owner. State that tagged
`go install` builds can obtain the main-module tag from Go build information,
controlled builds may inject
`gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override`, and an
ordinary unversioned checkout reports `development`.
### Tests
- Add table-driven `internal/buildinfo` tests for valid stable versions,
leading-zero rejection, whitespace, prerelease/build suffixes, pseudo-
versions, override precedence, invalid nonempty override, and development
fallback. Test the pure resolution decision rather than trying to mutate
process build information.
- Extend the CLI command-contract tests to cover exact stdout/stderr/exit
behavior for `--version`, extra arguments, and unchanged help/unknown-command
behavior.
- Do not snapshot the whole usage document solely for the new line; assert the
stable semantic fragments already owned by the CLI contract tests.
### Validation
```sh
go test ./internal/buildinfo ./internal/cli
go test ./...
go vet ./...
go build ./cmd/notarius
go run ./cmd/notarius --version
```
Build a temporary Linux host binary with:
```sh
go build -trimpath \
-ldflags '-X gitea.maximumdirect.net/eric/notarius/internal/buildinfo.Override=v0.0.0' \
-o /path/to/temp/notarius ./cmd/notarius
```
and verify that its output is exactly `notarius v0.0.0`.
### Acceptance Criteria
- The public and internal documentation matches the implemented version
behavior.
- Ordinary builds print `notarius development`.
- A valid linker override prints the exact stable tag.
- Invalid linker content cannot masquerade as a release version.
- Existing CLI commands, help, streams, and exit classes remain unchanged.
## Stage 2: Add One Reusable Source-Candidate Checker
### Goal
Create one repository-owned, offline validation command used identically by a
maintainer and release CI.
### Implementation
1. Create executable POSIX shell script `scripts/check-release-source.sh`.
Require exactly one positional argument containing a stable SemVer tag. The
script must locate and enter the repository root from its own checked-in
path so callers cannot accidentally validate another working directory.
2. Use `set -eu`, quote all expansions, reject invalid versions before using
them in paths or linker arguments, and use a freshly created temporary
directory for cross-build output. Install a cleanup trap scoped only to that
resolved temporary directory.
3. Keep release-note, branch, remote, clean-worktree, and tag-existence guards
out of this script. Those publication-specific checks belong in
`docs/release.md` and tag CI. This script owns the substantive source checks
that both workflows share.
4. Implement these checks in a clear fail-fast order:
- require the expected Notarius module path in `go.mod`;
- reject tracked `go.work` or `go.work.sum`, an existing `vendor` directory,
and any `replace` directive in `go.mod`;
- `GOWORK=off go test -count=1 ./...`;
- `GOWORK=off go test -race -count=1 ./...`;
- `GOWORK=off go vet ./...`;
- `GOWORK=off go build ./...`;
- `GOWORK=off go mod tidy -diff`;
- require no output from `gofmt -l` for tracked Go files;
- `git diff --check` and `git diff --cached --check`;
- validate `examples/dnd-minimal.config.yml` and
`examples/dnd-complete.config.yml` for pipeline `dnd-session` using the
built or `go run` Notarius command;
- build `./cmd/notarius` with `CGO_ENABLED=0` for Linux `amd64` and `arm64`
and Darwin `amd64` and `arm64`; and
- inject the supplied tag through `internal/buildinfo.Override` in every
cross-build.
5. Execute the built command and verify exact `--version` output when the
current host GOOS/GOARCH matches one of the four targets. Do not attempt to
execute a foreign target.
6. Do not compile for Windows, write output beneath the repository, contact an
LLM provider, require credentials, or mutate tracked files.
### Tests And Validation
- Run the script with `v0.0.0` as a synthetic build version. It does not require
or create a corresponding release note or Git tag.
- Exercise its cheap argument guards separately with missing, extra, malformed,
prerelease, and leading-zero versions. These failures must occur before Go
tests or builds begin.
- Confirm temporary outputs are removed on success and ordinary command
failure. Do not add a large shell-test framework solely for this script;
retain focused automated tests only if they protect a realistic failure that
is not more clearly covered by executing the checker itself.
```sh
./scripts/check-release-source.sh v0.0.0
git status --short
```
### Acceptance Criteria
- One command runs every substantive source-candidate check required by the
feature roadmap.
- The command is deterministic, offline, credential-free, POSIX-compatible,
fail-fast, and safe with temporary paths.
- The Linux and Darwin target matrix succeeds and Windows is absent.
- Version injection and host-binary reporting are checked as part of the same
matrix.
- Successful execution leaves the worktree and index unchanged.
## Stage 3: Add Validation-Only Tag CI
### Goal
Independently validate every newly pushed release tag without publishing or
mutating release state.
### Implementation
1. Add `.woodpecker/release.yml` triggered only by tag events.
2. Use the Go 1.25.5 container image to match the version currently declared
by `go.mod`. When the declared Go version changes in a future release, the
release pipeline image and release documentation must be reviewed in the
same change.
3. In one validation step:
- read the candidate version only from `CI_COMMIT_TAG`;
- require the stable SemVer form fixed above;
- require a nonempty `docs/releases/$CI_COMMIT_TAG.md`;
- require the exact heading `# Notarius $CI_COMMIT_TAG`;
- require exact `## Summary`, `## Compatibility`, `## Upgrade`, and
`## Changes` headings; and
- invoke `./scripts/check-release-source.sh "$CI_COMMIT_TAG"`.
4. Do not include a release plugin, API token, artifact upload, Gitea release
creation, archive/checksum step, Windows target, tag mutation, or retry that
could overwrite published state.
5. Keep the CI file thin: note/tag guards belong in it, while the substantive
source checks remain in the shared script.
### Validation
- Review the YAML trigger and commands against the repository's Woodpecker
syntax and the established Weatherreporter tag pipeline structure.
- Confirm every invoked path exists and the script is executable.
- Run the shared checker locally with `v0.0.0`.
- Search the new pipeline for release-plugin configuration, upload commands,
secrets, Windows targets, and mutation commands; none may be present.
- Run `git diff --check`.
Do not push a synthetic tag merely to test this stage. The first real release
will exercise the remote trigger; local source validation and review provide
the pre-release confidence boundary.
### Acceptance Criteria
- Every stable release tag triggers the validation pipeline.
- Missing or malformed version-matched release notes fail before the expensive
source checks.
- CI calls the same substantive checker used locally.
- The pipeline cannot publish binaries, releases, checksums, or other assets
and requires no release secret.
## Stage 4: Establish The Canonical Release Procedure And Documentation Policy
### Goal
Make the complete source-release workflow executable by a maintainer without
undocumented knowledge, and give release documentation an explicit canonical
home.
### Implementation
1. Create `docs/release.md`, adapted to Notarius's source-only model. It must
define:
- stable SemVer selection and the pre-`v1` compatibility policy;
- the exact `docs/releases/<tag>.md` template and validation guards;
- invocation of `./scripts/check-release-source.sh "$RELEASE_VERSION"`;
- manual review of changed Markdown links and unintended repository files;
- committing and pushing the release note and current documentation before
tagging;
- recording `RELEASE_COMMIT` from `HEAD^{commit}`;
- a copyable guard that requires `main`, a clean worktree/index, disabled Go
workspace use, an exact match between `RELEASE_COMMIT` and
`origin/main`, a matching note, and an unused local and remote tag;
- explicit lightweight-tag creation against `RELEASE_COMMIT`;
- pushing only
`refs/tags/$RELEASE_VERSION:refs/tags/$RELEASE_VERSION`;
- remote tag and tagged-note verification;
- a fresh `go install ...@"$RELEASE_VERSION"` or fresh exact-tag checkout
verification, including exact `--version` output; and
- immutable-tag failure and correction policy.
2. The procedure must say that the tag and checked-in note are the release and
that tag CI is validation-only. It must explicitly exclude binaries,
archives, checksums, signatures, containers, package-manager publication,
Gitea release objects, Windows, and retrospective notes for existing tags.
3. Document private-module installation through standard `GOPRIVATE` and Git
authentication mechanisms without including credentials or private
environment dumps. Do not make one maintainer's credential setup part of
the release contract.
4. Update `docs/policy/documentation.md`:
- add canonical-owner rows for `docs/release.md` and `docs/releases/`;
- state that release notes are historical summaries, not current-state
contract owners;
- state that the checked-in note at the immutable tag is the release record;
and
- require current canonical docs to change with behavior rather than using
release notes as substitutes.
5. Update `docs/development.md` with a release-preparation/tagging/verification
routing row pointing to `docs/release.md` and the relevant policies.
6. Do not create an empty placeholder release note or a retrospective note.
`docs/releases/` first becomes tracked when the next actual release note is
prepared.
### Validation
- Follow every local Markdown link added or changed in this stage.
- Execute every non-destructive candidate-validation command that does not
require an actual new release note, remote tag, or publication.
- Compare the procedure line by line with the shared checker and CI so their
tag syntax, note headings, target matrix, and validation ownership agree.
- Confirm the procedure never uses `git push --tags`, moves a published tag,
uploads an asset, or embeds credentials.
- Run `git diff --check`.
### Acceptance Criteria
- `docs/release.md` is sufficient to prepare, guard, tag, publish, verify, and
recover from a source release.
- Release procedure and release-note ownership are explicit and nonduplicative.
- The procedure calls the shared checker rather than restating its full command
matrix.
- No historical or placeholder release note is introduced.
## Stage 5: Align Platform, Installation, And Operational Documentation
### Goal
Make the supported-platform and source-installation story discoverable in the
canonical current-state documents without duplicating the release procedure.
### Implementation
1. Update `README.md` with a concise source-installation section. Show
`go install gitea.maximumdirect.net/eric/notarius/cmd/notarius@<tag>` as a
version-pinned pattern and retain the existing minimal product quickstart.
Link release maintainers to `docs/release.md` rather than reproducing its
guards.
2. Update `docs/operations.md` with operator-facing source deployment facts:
Linux support, the Go version declared by `go.mod`, version pinning, exact
tag builds, and `notarius --version` as a diagnostic. Link command semantics
to `docs/cli.md` and maintainer publication mechanics to `docs/release.md`.
3. Update `docs/policy/architecture.md` with the durable platform and
distribution invariants: supported Linux deployment, best-effort macOS
development, unsupported Windows, and source-only distribution. Keep tag
commands and release mechanics out of architecture.
4. Review `docs/internal/overview.md` navigation after adding
`internal/buildinfo`. Add only the smallest component entry needed if the
current inventory would otherwise omit a meaningful implemented boundary;
do not inflate build information into a subsystem.
5. Confirm `docs/roadmap/future.md` no longer lists the active documented
release-process work. Retain packaged alpha artifacts as deferred work; the
source-only release feature does not permanently reject reconsideration.
6. Review the completed feature roadmap against the implementation and correct
only genuine target-state inconsistencies. Do not convert it into a
changelog or duplicate `docs/release.md`.
### Validation
- Verify all added and changed local Markdown links.
- Confirm commands agree with the implemented CLI and declared module path.
- Confirm no current-state document claims that Notarius publishes binary
assets or supports Windows.
- Run:
```sh
go run ./cmd/notarius --version
go run ./cmd/notarius help
git diff --check
```
### Acceptance Criteria
- Users can discover how to install a pinned source release.
- Operators can identify the deployed version and understand the support
boundary.
- Architecture records durable platform/distribution policy without owning
maintainer release commands.
- Packaged artifacts remain clearly deferred rather than accidentally promised
or permanently prohibited.
## Stage 6: Final Release-System Verification
### Goal
Review the implemented feature as one system and prove that code,
documentation, shared validation, and CI converge on the same release model.
### Verification Work
1. Inspect all commits associated with Stages 15 and compare the result with
`docs/roadmap/source-releases.md` and this plan.
2. Run the shared candidate checker with synthetic version `v0.0.0`. This is a
build identity only; do not create a note or tag for it.
3. Independently run the repository-wide baseline checks if any are not already
performed by the shared checker:
```sh
go test ./...
go vet ./...
go build ./cmd/notarius
```
4. Verify exact development and injected release output:
- ordinary checkout: `notarius development`;
- injected `v0.0.0`: `notarius v0.0.0`;
- invalid linker override: nonzero exit, no false release identity.
5. Confirm both maintained D&D configurations validate offline.
6. Verify all added or changed local Markdown links and run
`git diff --check`.
7. Audit `.woodpecker/release.yml` and `docs/release.md` for agreement on tag
form, note location/headings, Go image/version expectations, and shared
checker use.
8. Confirm the repository contains no generated release binary, distribution
directory, checksum file, release credential, Windows target, release
plugin, synthetic release note, or new tag.
9. Review tests under the repository testing policy. Retain behavior-level
coverage for the public version contract and important validation guards;
remove redundant tests that merely duplicate the shared checker or CI text.
10. Report any remaining divergence as a concrete finding. Fix only in-scope
release-feature defects discovered during this verification; do not expand
into packaged distribution or unrelated cleanup.
### Acceptance Criteria
- All feature-roadmap acceptance criteria are met except creation of the first
real post-procedure release, which is intentionally a separate operator
action.
- Local validation and tag CI share one substantive source checker.
- Version reporting, source installation, platform policy, documentation
ownership, tag guards, and immutable failure handling are internally
consistent.
- The full test suite, vet, build, configuration validation, four-target cross-
build matrix, Markdown link review, and whitespace checks pass.
- The worktree contains no release side effects beyond the intended source,
automation, and documentation changes.

View File

@@ -0,0 +1,281 @@
# Source-Only Releases
## Status
Proposed.
## Purpose
Define a repeatable, guarded release process for Notarius without taking on a
binary-distribution system that its current operator audience does not need.
The process should make an exact source revision, its compatibility impact,
and its validation status easy to identify while keeping installation in the
hands of technically capable operators and deployment automation.
The model is adapted from Weatherreporter's release procedure, but its target
is deliberately narrower: an immutable source tag and checked-in release note
are the release. Notarius does not publish executable archives or support
Windows as part of this work.
## Release Model
Notarius releases come from commits on `main` and use stable semantic-version
tags in the form `vMAJOR.MINOR.PATCH`. Prerelease tags are not part of the
initial process.
Every release has one nonempty, version-matched note at
`docs/releases/<tag>.md`. The note and every affected current-state document
must be present in the tagged commit. The Git tag and checked-in note together
are the durable release record; no separately editable release page is
required.
Published tags are immutable. A maintainer must never move, reuse, or delete a
published tag. If a published candidate is defective, the correction is made
on `main` and released under a new patch version. An unpublished local tag may
be deleted when candidate inspection finds a problem before any remote push.
Before `v1.0.0`, a minor release may intentionally change a documented CLI,
configuration, durable artifact, integration, or operating contract when its
release note explains the impact and required operator action. A patch release
must not intentionally break those documented contracts within its minor
line.
The existing `v0.1.0`, `v0.2.0`, and `v0.3.0` tags remain unchanged. They
predate this procedure and do not need retrospective release notes. The first
release made under this process establishes the release-note series.
## Source-Only Distribution
Notarius does not publish release binaries, archives, installers, container
images, package-manager entries, checksum files, or signatures. A release tag
is suitable for Go-native installation and for an operator-controlled build
from an exact checkout.
The primary installation form is:
```sh
GOWORK=off go install \
gitea.maximumdirect.net/eric/notarius/cmd/notarius@vMAJOR.MINOR.PATCH
```
Operator documentation should also describe cloning the repository, checking
out the tag in detached-head state, and building `./cmd/notarius` with the Go
version declared by `go.mod`. Private-module authentication and `GOPRIVATE`
configuration belong to the operator environment and must be documented by
mechanism rather than with real credentials.
Consumers such as Narratio should pin the desired Notarius tag in provisioning
or deployment configuration. They must continue to decide runtime
compatibility from Notarius's published receipt and artifact schema contracts,
not merely from the executable's product version.
Packaged binaries may be reconsidered if distribution demand, installation
friction, or a broader user audience justifies their build, signing, retention,
and platform-support costs. They are not a prerequisite for a disciplined
release process.
## Platform Policy
Linux is the supported deployment platform. Release validation must run the
test suite and the release build on Linux and must confirm that the command
builds with `CGO_ENABLED=0` for Linux `amd64` and `arm64`.
macOS is a best-effort development and testing platform. Release validation
should confirm that the command cross-compiles with `CGO_ENABLED=0` for Darwin
`amd64` and `arm64`, but the project does not promise packaged artifacts or a
separate runtime test environment for those targets.
Windows is unsupported. The release process must not require Windows builds,
Windows-specific compatibility work, or Windows documentation. Platform-
specific implementation may intentionally use Unix facilities when they are
important to Notarius's filesystem safety and operational model. Any later
decision to support Windows requires its own feature scope and validation
policy.
## Version Reporting
Add a root `notarius --version` interface for deployment diagnostics. It
prints exactly one line:
```text
notarius vMAJOR.MINOR.PATCH
```
when the build has a valid release version, and:
```text
notarius development
```
when no release version is available.
The implementation must obtain the main-module version from Go build
information so `go install ...@vMAJOR.MINOR.PATCH` reports the selected tag. It
must also accept an optional link-time version override so controlled builds
and release CI can identify an exact tag from a checkout. The override must be
validated and must not silently turn arbitrary text into a release version.
Ordinary unversioned checkout builds remain `development`; the release process
must not modify a tracked source constant for each release.
Version reporting is an informational product interface. It does not replace
receipt, configuration, prompt, or artifact schema versioning, and it must not
be used as the sole downstream compatibility check.
## Release Notes
Each new `docs/releases/<tag>.md` document has this minimum structure:
```markdown
# Notarius vMAJOR.MINOR.PATCH
This release ...
## Summary
## Compatibility
## Upgrade
## Changes
```
The note should concisely explain the release's purpose, compatibility with the
preceding release, operator actions, and material user-visible, operational,
integration, and maintainer-visible changes. It should link to canonical
current-state documentation for exact contracts rather than duplicating those
contracts.
Release notes are durable historical summaries. They must not contain
credentials, private infrastructure detail, sensitive campaign material, or
claims that are not true of the tagged candidate. A release note does not
excuse stale current-state documentation; affected canonical documents are
updated in the same candidate.
## Candidate Validation
The release procedure must provide copyable POSIX-shell guards that validate
the release version, release-note filename and heading, required note sections,
repository state, and module hygiene. Validation must be run from the Notarius
repository root with Go workspace behavior disabled.
At minimum, a candidate must pass:
- no tracked `go.work` or `go.work.sum`, no vendored tree, and no `replace`
directive in `go.mod`;
- `GOWORK=off go test -count=1 ./...`;
- `GOWORK=off go test -race -count=1 ./...`;
- `GOWORK=off go vet ./...`;
- `GOWORK=off go build ./...`;
- `GOWORK=off go mod tidy -diff`;
- `gofmt` verification for every tracked Go file;
- `git diff --check` and `git diff --cached --check`;
- validation of both maintained D&D configuration examples with their selected
pipeline;
- Linux `amd64` and `arm64` static command builds;
- best-effort Darwin `amd64` and `arm64` static command builds; and
- a focused manual or automated check that every added or changed local
Markdown link resolves.
The candidate review also checks for generated binaries, test output,
credentials, temporary files, module replacements, vendored dependencies, and
other unintended source-control content. Tests remain offline and do not call
an LLM provider or require live credentials.
## Candidate Publication
The release procedure must guard the exact commit immediately before tagging.
It requires:
- the current branch is `main`;
- the worktree and index are clean;
- the candidate commit has been pushed and exactly matches `origin/main`;
- the matching release note exists in that commit;
- no local or remote tag already uses the selected version; and
- the substantive release checks have passed for that exact candidate.
The maintainer records the exact candidate commit, creates a lightweight tag
bound explicitly to that commit, verifies the local tag target, and pushes only
that tag ref. The procedure must not recommend `git push --tags`.
After publication, the maintainer verifies that the remote tag resolves to the
guarded commit and that the release note can be read from the tagged tree. A
fresh temporary checkout or `go install ...@<tag>` must build successfully, and
the resulting command must report the expected version through `--version`.
## Validation-Only Release Automation
Add a tag-triggered Woodpecker pipeline that validates source releases without
publishing artifacts. It should:
- accept only stable semantic-version tags;
- require the version-matched release note;
- run the same substantive module, test, race, vet, build, formatting, and
whitespace checks as the documented local procedure;
- validate the maintained configuration examples;
- perform the supported and best-effort cross-build checks; and
- verify a release-version build's `notarius --version` output on the CI host.
The pipeline must not upload binaries, create archives or checksums, create or
edit a Gitea release object, or require a release API token. Local guards remain
authoritative before tag publication because CI begins only after the tag is
already remote.
If tag validation fails, preserve the published tag, fix the cause on `main`,
select a new patch version, and repeat the full process. Do not weaken tag
immutability merely because the release contains source rather than binaries.
## Documentation Ownership
In the target state:
- `docs/release.md` owns the maintainer release procedure, commands, ordering,
publication checks, and failure recovery;
- `docs/releases/` owns one historical summary per release made under the new
process;
- `docs/cli.md` owns the `--version` contract;
- `README.md` owns the shortest source-installation example and links to the
release procedure where useful;
- `docs/development.md` routes release preparation, tagging, and verification
work to `docs/release.md`;
- `docs/policy/documentation.md` assigns canonical ownership to the release
procedure and release notes;
- `docs/policy/architecture.md` records Linux support, best-effort macOS
development, unsupported Windows, and source-only distribution only if those
are judged durable development invariants rather than release mechanics; and
- `docs/operations.md` describes only installation or deployment consequences
relevant to operators and links to canonical CLI and release contracts.
Current-state documentation must not describe the new release process,
`--version`, or automated validation until the corresponding behavior exists.
## Acceptance Criteria
- A maintainer can prepare, validate, tag, publish, and verify a source release
by following `docs/release.md` without relying on undocumented knowledge.
- Every new release has an immutable semantic-version tag and matching
checked-in release note in the tagged commit.
- The guarded candidate is clean, synchronized with `origin/main`, and passes
the documented substantive checks before tagging.
- Tag-triggered CI independently validates the published source and never
publishes binary artifacts.
- `go install` of a tagged version succeeds and `notarius --version` reports
that version; ordinary unversioned builds report `development`.
- Linux is the documented supported deployment platform, macOS has a
best-effort development build check, and Windows is explicitly unsupported.
- Downstream compatibility remains based on durable Notarius contracts rather
than the product version alone.
- Existing pre-procedure tags remain untouched and require no invented release
history.
## Non-Goals
- Publishing executable archives, installers, container images, checksums,
signatures, or package-manager entries.
- Supporting or cross-compiling for Windows.
- Creating or maintaining a mutable Gitea release page.
- Supporting prerelease tag syntax in the initial procedure.
- Automating version selection, release-note authorship, commits, or tag
creation.
- Retrospectively creating release notes for `v0.1.0` through `v0.3.0`.
- Treating a product version as a substitute for receipt, configuration,
prompt, or artifact schema compatibility.