Align repository policies with shared standards
This commit is contained in:
@@ -10,6 +10,10 @@ polished transcripts and generated artifacts. Start with the
|
||||
[Architecture](policy/architecture.md) for normative system boundaries, and the
|
||||
[Internal Overview](internal/overview.md) for implemented component ownership.
|
||||
|
||||
Agents must read [Agent Policy](policy/agents.md) before recommending, planning,
|
||||
or implementing changes. It owns implementation discipline and the default
|
||||
commit-after-completed-work rule; it does not authorize pushing or releasing.
|
||||
|
||||
## Go Prerequisite
|
||||
|
||||
Maintained development and verification require Go 1.26. Use the official Go
|
||||
@@ -30,7 +34,7 @@ Maintained development and verification require Go 1.26. Use the official Go
|
||||
| Adapters or external tool contracts | [Adapter Internals](internal/adapters.md) and [Integration Contracts](integrations/README.md) | The internal guide owns adapter composition and mechanics; integration documents own external formats and protocols. |
|
||||
| Manifests, artifacts, workspace paths, or publish behavior | [Manifest Internals](internal/manifest.md), [Artifact Internals](internal/artifacts.md), [Workspace Internals](internal/workspace.md), [Publish Internals](internal/stage-publish.md), and [Operations](operations.md) | These separate implementation state and resolution from operator-visible layout and lifecycle. |
|
||||
| Maintained configuration or input examples | [Configuration](config.md) and [Examples](../examples/README.md) | The reference owns field meanings; the examples directory owns complete copyable files. |
|
||||
| Preparing, validating, or publishing a release | [Release Procedure](release.md) | The maintainer procedure owns version selection, candidate validation, guarded tag publication, and optional later CI inspection. |
|
||||
| Preparing, validating, or publishing a release | [Release Policy](policy/release.md) and [Release Procedure](release.md) | Policy owns requirements and exceptions; the procedure owns concrete validation, guarded publication, and optional later inspection. |
|
||||
| Proposed or unimplemented behavior | `docs/roadmap/` | Future work belongs only in roadmap documentation until implemented. |
|
||||
|
||||
For an existing subsystem, also inspect its focused tests and package-level
|
||||
|
||||
95
docs/policy/agents.md
Normal file
95
docs/policy/agents.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# Agent Policy
|
||||
|
||||
**Base Policy Version:** 1.1
|
||||
|
||||
**Last Updated**: 2026-09-25
|
||||
|
||||
## Purpose
|
||||
|
||||
Agents working in this repository must read and adhere to the following house rules.
|
||||
|
||||
## Implementation Discipline
|
||||
|
||||
**KEY PRINCIPLES:** Write the simplest idiomatic code that satisfies the user's
|
||||
request. Do not implicitly strengthen requirements, restrictions, or guarantees
|
||||
beyond what the user actually requested.
|
||||
|
||||
Simplify the mechanism, not the user's choices.
|
||||
|
||||
**Keep implementation machinery proportionate.** Use straightforward,
|
||||
idiomatic code and introduce only the machinery needed to support the requested
|
||||
behavior and flexibility. Optimize for conceptual simplicity and
|
||||
maintainability, not for the fewest lines, fewest options, or narrowest product
|
||||
surface.
|
||||
|
||||
**Do not invent restrictions.** Do not reject, prohibit, constrain, cap,
|
||||
harden, or otherwise narrow behavior unless required by the user, an explicit
|
||||
repository contract, or an unavoidable correctness constraint. Preserve
|
||||
operator and caller choice where policy has not been established. If an
|
||||
additional restriction appears advisable, present it as a decision rather than
|
||||
silently implementing it.
|
||||
|
||||
A correctness constraint must follow from the requested behavior or an
|
||||
established invariant, not from the convenience of the chosen implementation.
|
||||
Explain the specific failure it prevents and why a less restrictive
|
||||
implementation cannot satisfy the contract.
|
||||
|
||||
**Do not invent guarantees.** Do not strengthen public contracts, guarantees,
|
||||
or invariants beyond those expressly requested by the user.
|
||||
|
||||
**Use the standard library.** For example: in almost every case, the best
|
||||
approach to copying files is to use the standard library. Writing custom code to
|
||||
implement power-loss protection at the application level, or to guard against
|
||||
bad actors with privileged and concurrent access to the host's filesystem,
|
||||
is wasteful, unnecessary, and not idiomatic. Stick to the simple, standard, and
|
||||
idiomatic approach unless another path is expressly requested by the user.
|
||||
|
||||
**An implementation detail is not repository policy.** Tests and documentation
|
||||
must not elevate incidental behavior into a durable guarantee or restriction
|
||||
unless that behavior was expressly selected as part of the contract. Existing
|
||||
explicit contracts remain authoritative; changing or weakening one requires a
|
||||
deliberate decision rather than being inferred from this principle.
|
||||
|
||||
Agent-authored plans, tests, documentation, and prior implementations are not
|
||||
evidence that an additional restriction was deliberately approved. Identify the
|
||||
authorizing requirement or decision; when that authority is unclear, surface
|
||||
the ambiguity rather than treating repetition as approval.
|
||||
|
||||
Standard-library guidance does not authorize weakening Narratio's established
|
||||
filesystem, manifest, or publication contracts. Preserve them unless a deliberate
|
||||
decision changes them.
|
||||
|
||||
## Git Commit Policy
|
||||
|
||||
By default, create a commit after completing each coherent unit of work, using a
|
||||
concise, plain-English message describing what changed. This policy is standing
|
||||
authorization to create those local commits; a separate user request is not
|
||||
required. An explicit user instruction to leave work uncommitted takes precedence.
|
||||
|
||||
A unit of work is a focused, reviewable outcome, including its relevant tests and
|
||||
documentation. Do not commit after every intermediate edit or create empty commits.
|
||||
Complete the appropriate validation before committing. If work is incomplete or
|
||||
validation is blocked, report that state rather than presenting it as completed.
|
||||
|
||||
Before committing:
|
||||
|
||||
1. Run `git status --short` and review the relevant diff, including any staged
|
||||
changes. Identify changes that predate the current unit of work.
|
||||
2. Exclude secrets, local environment files, generated junk, and unrelated changes.
|
||||
3. Stage only the files or hunks belonging to the completed unit. Use `git add .`
|
||||
only when every included change belongs to that unit. Do not disturb unrelated
|
||||
staged or unstaged work.
|
||||
4. Review `git diff --staged` and run appropriate checks for the change. Do not
|
||||
repeat checks already passed for unchanged content merely to create a commit.
|
||||
5. Review `git log --oneline -n 10` and use
|
||||
`git commit -m "<concise plain-English commit message>"`.
|
||||
6. Report the commit identifier and any remaining uncommitted work.
|
||||
|
||||
If the unit cannot be safely separated from pre-existing work, leave it uncommitted
|
||||
and explain the overlap rather than silently including that work. If a commit
|
||||
fails, preserve the changes and report the failure; do not bypass hooks.
|
||||
|
||||
Default commit authorization does not authorize pushing, publishing, amending,
|
||||
resetting, reverting, or rewriting history. Those actions require a separate user
|
||||
instruction. Do not use `git commit -a` or `git commit --no-verify` to bypass the
|
||||
staging and validation discipline above.
|
||||
@@ -1,5 +1,9 @@
|
||||
# Architecture
|
||||
|
||||
**Base Policy Version:** 1.0
|
||||
|
||||
**Last Updated**: 2026-09-25
|
||||
|
||||
This document defines Narratio's intended high-level architecture and the
|
||||
invariants that changes must preserve. Implemented component details belong in
|
||||
the [Internal Overview](../internal/overview.md) and its linked documents.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Documentation Policy
|
||||
|
||||
**Base Policy Version:** 1.1
|
||||
|
||||
**Last Updated**: 2026-09-25
|
||||
|
||||
## Purpose
|
||||
|
||||
This policy assigns each documentation topic to one canonical owner. Its goal is
|
||||
@@ -59,7 +63,9 @@ secret values.
|
||||
| --- | --- | --- | --- |
|
||||
| Product orientation and minimal end-to-end quickstart | `README.md` | What Narratio is, why it is useful, one shortest successful invocation, and links onward. | Complete command reference, configuration reference, operational procedures, implementation detail. |
|
||||
| Contributor entry point | `docs/development.md` | Task-oriented reading guide, minimal contributor orientation, baseline validation commands, and links to canonical docs. | Package inventory, architecture rules, subsystem behavior, detailed change recipes. |
|
||||
| Maintainer release procedure | `docs/release.md` | Version selection, candidate preparation and validation, guarded tag publication, release completion boundary, failure recovery, and optional asynchronous inspection. | Script implementation mechanics, current application contracts, and historical release summaries. |
|
||||
| Agent policy | `docs/policy/agents.md` | Agent implementation discipline, authority boundaries, and local commit policy. | Application contracts, architecture, testing policy, and contributor procedures. |
|
||||
| Release policy | `docs/policy/release.md` | Versioning, release integrity, documentation and validation requirements, immutability, publication controls, and explicit exceptions. | Repository-specific commands, installation, historical summaries, and CI implementation detail. |
|
||||
| Maintainer release procedure | `docs/release.md` | Prerequisites, concrete candidate validation and publication commands, deliverables, failure recovery, and optional consumer-facing inspection. | General release requirements and exceptions, current application contracts, and historical release summaries. |
|
||||
| Historical release summary | `docs/releases/<tag>.md` | Immutable summary, compatibility, upgrade, and changes for one released version. | Current maintainer procedure and current application contract details. |
|
||||
| Current application architecture | `docs/policy/architecture.md` | System shape, normative ownership, dependency direction, architectural boundaries, invariants, safety properties, and non-goals. | Concrete package inventory, implementation mechanics, contributor procedures, decision history, future work. |
|
||||
| Documentation organization | `docs/policy/documentation.md` | Documentation ownership, audience boundaries, maintenance rules, and ADR/document lifecycle. | Application architecture or product behavior. |
|
||||
@@ -100,6 +106,14 @@ configuration, operational, or integration contract. When a workflow crosses
|
||||
these topics, choose the document that owns the task and link to the other
|
||||
contracts.
|
||||
|
||||
### Releases
|
||||
|
||||
[Release policy](release.md) owns requirements and explicit exceptions;
|
||||
[the release procedure](../release.md) owns the commands used to satisfy them.
|
||||
Release notes record history at an immutable tag. Neither the procedure nor a
|
||||
release note may silently weaken policy or substitute for updates to current
|
||||
canonical documentation.
|
||||
|
||||
### Contracts And Implementation
|
||||
|
||||
Integration and API documents define externally observable shapes and
|
||||
|
||||
221
docs/policy/release.md
Normal file
221
docs/policy/release.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# Release Policy
|
||||
|
||||
**Base Policy Version:** 1.0
|
||||
|
||||
**Last Updated**: 2026-09-25
|
||||
|
||||
## Purpose
|
||||
|
||||
This policy defines the minimum requirements for selecting, validating,
|
||||
publishing, verifying, and correcting releases. Its goal is to make every
|
||||
release intentional, reproducible from an exact source revision, documented
|
||||
for consumers, and safe from retrospective replacement.
|
||||
|
||||
The repository-specific commands that implement these requirements belong in
|
||||
`docs/release.md`. Historical release summaries belong in `docs/releases/`.
|
||||
Neither document may weaken this policy, including its explicit repository
|
||||
exceptions.
|
||||
|
||||
## Release Model
|
||||
|
||||
A release consists of:
|
||||
|
||||
- one exact source commit reachable from the repository's primary branch;
|
||||
- one immutable version tag identifying that commit;
|
||||
- one version-matched, checked-in release note; and
|
||||
- every artifact, image, package, registry entry, or other deliverable the
|
||||
repository declares for that release.
|
||||
|
||||
The repository's primary branch is `main` unless an adopted policy documents
|
||||
an exception. A release candidate must be committed and pushed to that branch
|
||||
before its release tag is published.
|
||||
|
||||
The source tag is the authoritative release identity. Published deliverables
|
||||
must be traceable to the tagged source and must agree with its version. A
|
||||
repository may publish source only. When it publishes additional deliverables,
|
||||
its release procedure must enumerate them and define how each is built,
|
||||
identified, published, and verified.
|
||||
|
||||
Release automation may validate or publish a release only when its exact
|
||||
responsibility is documented. Automation must not silently change the source
|
||||
candidate, move a published tag, replace a published deliverable, or repair a
|
||||
release in place.
|
||||
|
||||
## Versioning And Compatibility
|
||||
|
||||
Stable releases use Semantic Versioning in the form `vMAJOR.MINOR.PATCH`, with
|
||||
no leading zeroes. Each version must be unused locally and in every configured
|
||||
remote or publication channel before publication begins.
|
||||
|
||||
Unless an adopted policy explicitly supports and defines prereleases,
|
||||
prerelease versions are not permitted.
|
||||
|
||||
For releases at or after `v1.0.0`:
|
||||
|
||||
- a major release may make intentional incompatible changes;
|
||||
- a minor release may add backward-compatible behavior; and
|
||||
- a patch release may make backward-compatible fixes.
|
||||
|
||||
Before `v1.0.0`, a minor release may change a documented public, operational,
|
||||
configuration, data, integration, or compatibility contract when the release
|
||||
note explains the impact and required consumer action. A patch release must
|
||||
not intentionally break those contracts within its minor line.
|
||||
|
||||
A repository with additional compatibility promises must define them in its
|
||||
adopted policy or canonical contract documentation. A release note may explain
|
||||
a compatibility change, but it must not redefine the current compatibility
|
||||
contract.
|
||||
|
||||
## Release Documentation
|
||||
|
||||
Every release made under this policy must include
|
||||
`docs/releases/<version>.md` in the tagged source tree. The filename must use
|
||||
the complete version tag, and the document must begin with a title containing
|
||||
the product name and that exact version.
|
||||
|
||||
Every new release note must contain these sections:
|
||||
|
||||
```markdown
|
||||
# <Product> vMAJOR.MINOR.PATCH
|
||||
|
||||
This release ...
|
||||
|
||||
## Summary
|
||||
|
||||
## Compatibility
|
||||
|
||||
## Upgrade
|
||||
|
||||
## Changes
|
||||
```
|
||||
|
||||
Use an explicit statement such as "No action required" when a section has no
|
||||
substantive content.
|
||||
|
||||
Release notes are immutable historical summaries. They should link to current
|
||||
canonical documentation for exact behavior. Every affected canonical document
|
||||
must be updated in the same candidate; a release note must not substitute for
|
||||
current documentation or defer required documentation changes.
|
||||
|
||||
## Candidate Preparation And Validation
|
||||
|
||||
Each repository must provide one documented release-check command or script
|
||||
that exercises the complete set of automated source-candidate gates. The
|
||||
repository-specific procedure must state all additional manual gates.
|
||||
|
||||
The required gates are:
|
||||
|
||||
- dependency or module hygiene appropriate to the language and ecosystem;
|
||||
- the complete deterministic, offline default test suite;
|
||||
- static analysis and linting used by the repository;
|
||||
- formatting and whitespace checks;
|
||||
- validation of maintained examples, configuration, schemas, generated
|
||||
sources, and documentation commands where applicable;
|
||||
- review of changed local documentation links;
|
||||
- removal of obsolete roadmap documents under `docs/roadmap/` that describe
|
||||
completed work included in the release; and
|
||||
- review for unintended files, generated output, credentials, private data,
|
||||
and unrelated changes.
|
||||
|
||||
## Publication Guards
|
||||
|
||||
Immediately before publication, the maintainer or release automation must
|
||||
fetch the current primary branch and tags from the authoritative remote and
|
||||
verify all of the following:
|
||||
|
||||
- the version has the required format and is not already published;
|
||||
- the current branch is the primary release branch;
|
||||
- the worktree and index are clean;
|
||||
- the current commit is the recorded, validated candidate;
|
||||
- the authoritative remote branch points to that same commit;
|
||||
- the matching release note exists in that commit and has the required title
|
||||
and sections;
|
||||
- all required approvals and automated gates succeeded for that commit; and
|
||||
- no local or remote tag already uses the selected version.
|
||||
|
||||
Create the version tag against the guarded commit and verify its target before
|
||||
publishing it. Publish only the exact intended ref and deliverables. Broad
|
||||
operations such as `git push --tags` are discouraged because they can publish
|
||||
unreviewed refs unrelated to the release.
|
||||
|
||||
The repository-specific procedure must make these guards executable or give
|
||||
copyable commands for performing them.
|
||||
|
||||
## Immutability And Correction
|
||||
|
||||
Published version tags and published deliverables are immutable. Do not move,
|
||||
overwrite, recreate, or delete a published tag. Do not replace an artifact,
|
||||
image, package, checksum, signature, provenance statement, or release note
|
||||
under an already published version.
|
||||
|
||||
If validation fails before publication, correct the candidate, rerun the
|
||||
complete gates, and repeat the publication guards. An unpublished local tag
|
||||
may be removed after confirming that it was never published or used by a
|
||||
release channel.
|
||||
|
||||
If publication or post-publication verification reveals a defect, leave the
|
||||
published release intact. Correct the defect on the primary branch, choose a
|
||||
new patch version or other semantically appropriate new version, write a new
|
||||
matching release note, and perform the complete release procedure again.
|
||||
|
||||
A distribution channel's supported yank, deprecation, or advisory mechanism
|
||||
may warn consumers away from a defective release, but it must not replace that
|
||||
release's contents or reuse its version.
|
||||
|
||||
## Repository Release Procedure
|
||||
|
||||
Every adopting repository must maintain `docs/release.md` as the canonical
|
||||
maintainer runbook for implementing this policy. It must define, in execution
|
||||
order:
|
||||
|
||||
1. maintainer prerequisites and required access;
|
||||
2. version selection and compatibility review;
|
||||
3. release-note creation;
|
||||
4. candidate preparation and the complete validation command;
|
||||
5. candidate commit, push, and exact commit recording;
|
||||
6. publication guards;
|
||||
7. exact tag and deliverable publication commands;
|
||||
8. authoritative remote and consumer-facing verification; and
|
||||
9. failure handling and correction.
|
||||
|
||||
The procedure should use copyable, fail-fast commands where practical. It must
|
||||
name the primary branch, authoritative remote, tag form, published
|
||||
deliverables, supported build targets, release automation responsibilities,
|
||||
and consumer verification path. It must link to this policy instead of
|
||||
restating or redefining its requirements.
|
||||
|
||||
## Policy Exceptions
|
||||
|
||||
### Tag-push completion and asynchronous deliverables
|
||||
|
||||
Narratio's automated release responsibility ends when the exact intended tag is
|
||||
successfully pushed to `origin`. It must not wait for, poll, or check CI/Gitea
|
||||
results, download assets, or verify their checksums as a completion condition.
|
||||
Binary and checksum publication is asynchronous; consumer-facing inspection is
|
||||
optional follow-up, not a gate on the source release.
|
||||
|
||||
This deliberately qualifies the base policy's complete-deliverable and
|
||||
post-publication verification requirements. CI reliability is outside the
|
||||
release command's scope; an unavailable publication service must not cause an
|
||||
automated releaser to wait indefinitely or claim to repair a published version.
|
||||
|
||||
Compensating controls are complete local candidate validation (including supported
|
||||
cross-builds and a host version check), exact source/tag guards, immutable source
|
||||
tags, asynchronous build validation, and non-overwriting asset publication.
|
||||
Successful tag publication is not evidence that binary assets are available.
|
||||
Optional inspection and corrective-release procedures belong in
|
||||
[the release procedure](../release.md).
|
||||
|
||||
### Authoritative publication scope
|
||||
|
||||
Narratio's synchronous publication guards inspect the authoritative `origin`
|
||||
remote and its `main` branch, not every configured Git remote or a Gitea release
|
||||
entry. The command does not add release-service or registry availability checks.
|
||||
This qualifies the base policy's all-channel unused-version requirement.
|
||||
|
||||
Other remotes are not Narratio release authorities, and Gitea asset publication
|
||||
is asynchronous. The compensating controls are local and origin tag uniqueness,
|
||||
exact candidate matching, and the publisher's non-overwrite settings. Any known
|
||||
already-published version or conflicting deliverable remains ineligible for
|
||||
reuse: choose a new version rather than bypassing guards. A future additional
|
||||
distribution channel requires deliberate policy/procedure updates.
|
||||
@@ -1,5 +1,9 @@
|
||||
# Testing Policy
|
||||
|
||||
**Base Policy Version:** 1.0
|
||||
|
||||
**Last Updated**: 2026-09-25
|
||||
|
||||
## Purpose
|
||||
|
||||
Our tests exist to make **incorrect changes expensive and correct changes cheap**.
|
||||
|
||||
173
docs/release.md
173
docs/release.md
@@ -1,71 +1,97 @@
|
||||
# Releasing Narratio
|
||||
|
||||
This document is the maintainer procedure for creating a Narratio source and
|
||||
binary release. The synchronous release boundary is a successful push of one
|
||||
new tag to `origin`; Woodpecker and Gitea publication happen later and do not
|
||||
change that result.
|
||||
This is the maintainer runbook for the [Release Policy](policy/release.md).
|
||||
Its [explicit exceptions](policy/release.md#policy-exceptions) preserve the
|
||||
successful tag push as the automated responsibility boundary. Binary publication
|
||||
is asynchronous; later consumer-facing inspection is optional.
|
||||
|
||||
## Prerequisites and publication scope
|
||||
|
||||
Use a checkout on `main` with Git authentication permitting fetches and pushes
|
||||
to `origin`, the authoritative Git remote. Install Git, a POSIX shell, standard
|
||||
Unix build tools, and the Go toolchain below. Make required modules available
|
||||
before offline validation. No model/provider credentials are needed. Gitea
|
||||
publication credentials belong to CI's secret store, not the local command.
|
||||
|
||||
Synchronous guards inspect local tags and `origin`, not every configured remote
|
||||
or Gitea release entry. Do not select a version known to have been published in
|
||||
any channel, even if these guards cannot see it.
|
||||
|
||||
## Go prerequisite
|
||||
|
||||
Release preparation requires the maintained Go 1.26 baseline. Tag CI currently
|
||||
uses the explicitly pinned `golang:1.26.7` image for candidate validation and
|
||||
asset construction; that asynchronous work does not change the tag-push
|
||||
completion boundary.
|
||||
uses the explicitly pinned `golang:1.26.7` image for validation and asset builds.
|
||||
That asynchronous work does not change the tag-push completion boundary.
|
||||
|
||||
## Choose a version and write its note
|
||||
|
||||
Narratio is past `v1.0.0`. Use an unused stable tag in the exact form
|
||||
`vMAJOR.MINOR.PATCH`:
|
||||
Select an unused stable version under the
|
||||
[versioning rules](policy/release.md#versioning-and-compatibility). Narratio is
|
||||
past v1.0.0; intentional CLI/configuration breaks require a major release.
|
||||
|
||||
- increment `MINOR` for backward-compatible features;
|
||||
- increment `PATCH` for backward-compatible fixes; and
|
||||
- reserve a new `MAJOR` for an intentional breaking documented contract.
|
||||
Create `docs/releases/vMAJOR.MINOR.PATCH.md` using the
|
||||
[required note structure](policy/release.md#release-documentation).
|
||||
Describe CLI, configuration, artifact, integration, and operating-contract
|
||||
changes, and the required operator action. Link to current canonical
|
||||
documentation for exact behavior.
|
||||
|
||||
Before preparing the candidate, create
|
||||
`docs/releases/vMAJOR.MINOR.PATCH.md` with this structure:
|
||||
## Prepare and record the candidate
|
||||
|
||||
```markdown
|
||||
# Narratio vMAJOR.MINOR.PATCH
|
||||
Before committing, perform these manual reviews in addition to automated checks:
|
||||
|
||||
This release ...
|
||||
- Confirm compatibility/version selection and update affected canonical
|
||||
documentation and maintained examples.
|
||||
- Remove completed roadmap documents covering work included in this release;
|
||||
retain pending work. Their history remains in Git. Do not delete historical
|
||||
release notes.
|
||||
- Review the diff, staged changes, and untracked files for credentials, private
|
||||
data, generated output, unintended files, and unrelated changes.
|
||||
- Review changed documentation links and behavior-bearing commands. Automated
|
||||
link checks supplement rather than replace review.
|
||||
|
||||
## Summary
|
||||
Commit the note and candidate changes, then push that commit to `main` through
|
||||
the ordinary development workflow. Record the exact candidate:
|
||||
|
||||
## Compatibility
|
||||
|
||||
## Upgrade
|
||||
|
||||
## Changes
|
||||
```sh
|
||||
git rev-parse HEAD
|
||||
```
|
||||
|
||||
The compatibility section identifies relevant CLI, configuration, artifact,
|
||||
integration, or operating-contract changes. The upgrade section states the
|
||||
required operator action, or explicitly says that no special action is
|
||||
required. Release notes are immutable historical summaries; link to the
|
||||
current canonical documentation for detailed behavior.
|
||||
|
||||
Commit the note and all candidate changes, then use the ordinary development
|
||||
workflow to push that commit to `main`. Do not create a release tag before the
|
||||
candidate is committed and `origin/main` contains the exact same commit.
|
||||
Do not create a tag until `origin/main` points to that same commit. If the
|
||||
candidate changes, repeat the reviews and validation.
|
||||
|
||||
## Validate the candidate
|
||||
|
||||
Run the shared checker from any directory:
|
||||
From the repository root, run:
|
||||
|
||||
```sh
|
||||
scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
The script also works when invoked by its absolute path from another directory.
|
||||
It validates the version and matching note, module hygiene, formatting,
|
||||
whitespace, uncached tests, race tests, static checks, documentation, examples,
|
||||
and three official cross-build assets. It uses `GOWORK=off`, does not contact
|
||||
application services, CI, or Gitea, and does not create tags or modify tracked
|
||||
source. Fix any failure on `main`, commit it, push it normally, and rerun the
|
||||
checker.
|
||||
and three cross-build assets. It uses `GOWORK=off`, does not contact application
|
||||
services, CI, or Gitea, and does not create tags or modify tracked source.
|
||||
Fix failures on `main`, commit, push normally, and rerun validation.
|
||||
|
||||
The checker builds Linux assets for `amd64` and `arm64` and a macOS asset for
|
||||
`arm64`. The macOS cross-build proves compilation; it is not native macOS
|
||||
runtime evidence.
|
||||
The macOS cross-build proves compilation, not native runtime behavior.
|
||||
|
||||
## Declared deliverables and automation
|
||||
|
||||
The source release is the exact version tag at the validated commit.
|
||||
The tag-triggered `.woodpecker/release.yml` validates the tagged source,
|
||||
runs `scripts/build-release-assets.sh`, and publishes these Gitea assets:
|
||||
|
||||
- `narratio-vMAJOR.MINOR.PATCH-linux-amd64`
|
||||
- `narratio-vMAJOR.MINOR.PATCH-linux-arm64`
|
||||
- `narratio-vMAJOR.MINOR.PATCH-darwin-arm64` (best effort)
|
||||
- `SHA256SUMS`
|
||||
|
||||
The builder embeds the version, disables ambient Go workspaces, and checks a
|
||||
host binary's `version` output. The release publisher uses the matching
|
||||
checked-in note and generates SHA-256 checksums. Existing files are skipped and
|
||||
overwrite is disabled. No image or package-registry deliverable is declared.
|
||||
CI does not choose versions, modify source candidates, or move tags.
|
||||
|
||||
## Publish the tag
|
||||
|
||||
@@ -78,27 +104,64 @@ scripts/release.sh vMAJOR.MINOR.PATCH
|
||||
The command fetches and checks `origin/main`, re-runs candidate validation,
|
||||
then fetches and checks again before creating an explicitly unsigned lightweight
|
||||
tag for the originally recorded commit. It refuses dirty, divergent, changed,
|
||||
or already-tagged candidates. It pushes only:
|
||||
or already-tagged candidates. It verifies the local tag target and pushes only:
|
||||
|
||||
```text
|
||||
refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH
|
||||
```
|
||||
|
||||
It never commits changes, pushes `main`, force-pushes, moves a tag, or pushes
|
||||
all tags. A successful push of that exact ref completes the release command;
|
||||
the command prints the tag and commit, then returns without waiting for CI,
|
||||
querying Gitea, downloading assets, or checking checksums.
|
||||
It never commits changes, pushes `main`, force-pushes, moves tags, or pushes all
|
||||
tags. Successful publication of that ref completes the command; it prints the
|
||||
tag and commit and returns without waiting for CI, querying Gitea, downloading
|
||||
assets, or checking checksums.
|
||||
|
||||
If a failure occurs before the tag is created, correct the candidate on `main`
|
||||
and repeat validation. If the push fails after local tag creation, the local tag
|
||||
is intentionally retained for inspection and the command must not be retried
|
||||
blindly. Once the upstream tag has been pushed, it is immutable. Correct any
|
||||
defect or failed asynchronous publication with a new patch version, a new
|
||||
release note, and the complete procedure again.
|
||||
## Failure handling
|
||||
|
||||
Before tag creation, correct the candidate on `main` and repeat validation.
|
||||
If a push fails after local tag creation, the local tag is retained for inspection.
|
||||
Do not retry blindly or assume the remote received nothing: a connection failure
|
||||
can leave publication uncertain. Inspect the exact remote ref before taking any
|
||||
local-tag cleanup action. This is recovery from a failed command, not a
|
||||
post-success publication gate.
|
||||
|
||||
After publication, follow the
|
||||
[immutability and correction rules](policy/release.md#immutability-and-correction).
|
||||
Correct defects or failed asynchronous publication with a new semantically
|
||||
appropriate version, matching note, and the complete procedure. Never replace
|
||||
existing tagged assets in place.
|
||||
|
||||
## Optional asynchronous inspection
|
||||
|
||||
After a successful tag push, a human may later inspect the tag-triggered
|
||||
Woodpecker run and the corresponding Gitea release for binaries and checksums.
|
||||
This is optional follow-up only. Automated releasers must not wait for, poll,
|
||||
or treat CI/Gitea completion as a condition of the successful tag push.
|
||||
A human may later inspect the tag-triggered Woodpecker job and Gitea release.
|
||||
This is optional follow-up, never part of the automated releaser's completion
|
||||
criteria. Do not wait for or poll CI/Gitea from the release command.
|
||||
|
||||
For optional source verification, substitute the released version below and
|
||||
compare the remote target to the recorded candidate hash:
|
||||
|
||||
```sh
|
||||
git ls-remote --tags origin refs/tags/vMAJOR.MINOR.PATCH
|
||||
git rev-parse 'refs/tags/vMAJOR.MINOR.PATCH^{commit}'
|
||||
```
|
||||
|
||||
Download the three named binaries and `SHA256SUMS` from the matching Gitea release
|
||||
into an empty inspection directory. In that directory, verify on Linux:
|
||||
|
||||
```sh
|
||||
sha256sum --check SHA256SUMS
|
||||
```
|
||||
|
||||
On macOS, use `shasum -a 256 --check SHA256SUMS`. After successful verification,
|
||||
make the matching host binary executable and run its version command, for example
|
||||
on Linux amd64 (replace the version in both commands):
|
||||
|
||||
```sh
|
||||
chmod +x ./narratio-vMAJOR.MINOR.PATCH-linux-amd64
|
||||
./narratio-vMAJOR.MINOR.PATCH-linux-amd64 version
|
||||
```
|
||||
|
||||
Expected output is `narratio vMAJOR.MINOR.PATCH`. Use only the matching architecture
|
||||
on other supported hosts. Checksums establish consistency with the downloaded
|
||||
checksum file, not a new signature or independent authenticity guarantee.
|
||||
Missing assets are an asynchronous publication problem, not grounds to move or
|
||||
reuse the successfully published source tag.
|
||||
|
||||
@@ -16,9 +16,9 @@ pass changes documentation only. Intermediate stages are not release candidates.
|
||||
Do not add compatibility code to make intermediate states look like a supported
|
||||
release.
|
||||
|
||||
Before each stage, read `AGENTS.md`, `docs/development.md`, and all three policies
|
||||
under `docs/policy/`: architecture, documentation, and testing. Read this plan's
|
||||
selected design and that stage's preparation. Use Go 1.26 and graph-first code
|
||||
Before each stage, read `AGENTS.md`, `docs/development.md`, and all policies
|
||||
under `docs/policy/`: agents, architecture, documentation, testing, and release.
|
||||
Read this plan's selected design and that stage's preparation. Use Go 1.26 and graph-first code
|
||||
discovery; inspect current files when graph results are incomplete. Preserve
|
||||
unrelated changes. Test at behavioral owners rather than replicating every case
|
||||
across configuration, adapter, stage, and command tests.
|
||||
|
||||
Reference in New Issue
Block a user