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
|
[Architecture](policy/architecture.md) for normative system boundaries, and the
|
||||||
[Internal Overview](internal/overview.md) for implemented component ownership.
|
[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
|
## Go Prerequisite
|
||||||
|
|
||||||
Maintained development and verification require Go 1.26. Use the official Go
|
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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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
|
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
|
# Architecture
|
||||||
|
|
||||||
|
**Base Policy Version:** 1.0
|
||||||
|
|
||||||
|
**Last Updated**: 2026-09-25
|
||||||
|
|
||||||
This document defines Narratio's intended high-level architecture and the
|
This document defines Narratio's intended high-level architecture and the
|
||||||
invariants that changes must preserve. Implemented component details belong in
|
invariants that changes must preserve. Implemented component details belong in
|
||||||
the [Internal Overview](../internal/overview.md) and its linked documents.
|
the [Internal Overview](../internal/overview.md) and its linked documents.
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
# Documentation Policy
|
# Documentation Policy
|
||||||
|
|
||||||
|
**Base Policy Version:** 1.1
|
||||||
|
|
||||||
|
**Last Updated**: 2026-09-25
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
This policy assigns each documentation topic to one canonical owner. Its goal is
|
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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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
|
these topics, choose the document that owns the task and link to the other
|
||||||
contracts.
|
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
|
### Contracts And Implementation
|
||||||
|
|
||||||
Integration and API documents define externally observable shapes and
|
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
|
# Testing Policy
|
||||||
|
|
||||||
|
**Base Policy Version:** 1.0
|
||||||
|
|
||||||
|
**Last Updated**: 2026-09-25
|
||||||
|
|
||||||
## Purpose
|
## Purpose
|
||||||
|
|
||||||
Our tests exist to make **incorrect changes expensive and correct changes cheap**.
|
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
|
# Releasing Narratio
|
||||||
|
|
||||||
This document is the maintainer procedure for creating a Narratio source and
|
This is the maintainer runbook for the [Release Policy](policy/release.md).
|
||||||
binary release. The synchronous release boundary is a successful push of one
|
Its [explicit exceptions](policy/release.md#policy-exceptions) preserve the
|
||||||
new tag to `origin`; Woodpecker and Gitea publication happen later and do not
|
successful tag push as the automated responsibility boundary. Binary publication
|
||||||
change that result.
|
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
|
## Go prerequisite
|
||||||
|
|
||||||
Release preparation requires the maintained Go 1.26 baseline. Tag CI currently
|
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
|
uses the explicitly pinned `golang:1.26.7` image for validation and asset builds.
|
||||||
asset construction; that asynchronous work does not change the tag-push
|
That asynchronous work does not change the tag-push completion boundary.
|
||||||
completion boundary.
|
|
||||||
|
|
||||||
## Choose a version and write its note
|
## Choose a version and write its note
|
||||||
|
|
||||||
Narratio is past `v1.0.0`. Use an unused stable tag in the exact form
|
Select an unused stable version under the
|
||||||
`vMAJOR.MINOR.PATCH`:
|
[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;
|
Create `docs/releases/vMAJOR.MINOR.PATCH.md` using the
|
||||||
- increment `PATCH` for backward-compatible fixes; and
|
[required note structure](policy/release.md#release-documentation).
|
||||||
- reserve a new `MAJOR` for an intentional breaking documented contract.
|
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
|
## Prepare and record the candidate
|
||||||
`docs/releases/vMAJOR.MINOR.PATCH.md` with this structure:
|
|
||||||
|
|
||||||
```markdown
|
Before committing, perform these manual reviews in addition to automated checks:
|
||||||
# Narratio vMAJOR.MINOR.PATCH
|
|
||||||
|
|
||||||
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
|
```sh
|
||||||
|
git rev-parse HEAD
|
||||||
## Upgrade
|
|
||||||
|
|
||||||
## Changes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The compatibility section identifies relevant CLI, configuration, artifact,
|
Do not create a tag until `origin/main` points to that same commit. If the
|
||||||
integration, or operating-contract changes. The upgrade section states the
|
candidate changes, repeat the reviews and validation.
|
||||||
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.
|
|
||||||
|
|
||||||
## Validate the candidate
|
## Validate the candidate
|
||||||
|
|
||||||
Run the shared checker from any directory:
|
From the repository root, run:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
scripts/check-release-candidate.sh vMAJOR.MINOR.PATCH
|
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,
|
It validates the version and matching note, module hygiene, formatting,
|
||||||
whitespace, uncached tests, race tests, static checks, documentation, examples,
|
whitespace, uncached tests, race tests, static checks, documentation, examples,
|
||||||
and three official cross-build assets. It uses `GOWORK=off`, does not contact
|
and three cross-build assets. It uses `GOWORK=off`, does not contact application
|
||||||
application services, CI, or Gitea, and does not create tags or modify tracked
|
services, CI, or Gitea, and does not create tags or modify tracked source.
|
||||||
source. Fix any failure on `main`, commit it, push it normally, and rerun the
|
Fix failures on `main`, commit, push normally, and rerun validation.
|
||||||
checker.
|
|
||||||
|
|
||||||
The checker builds Linux assets for `amd64` and `arm64` and a macOS asset for
|
The macOS cross-build proves compilation, not native runtime behavior.
|
||||||
`arm64`. The macOS cross-build proves compilation; it is not native macOS
|
|
||||||
runtime evidence.
|
## 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
|
## Publish the tag
|
||||||
|
|
||||||
@@ -78,27 +104,64 @@ scripts/release.sh vMAJOR.MINOR.PATCH
|
|||||||
The command fetches and checks `origin/main`, re-runs candidate validation,
|
The command fetches and checks `origin/main`, re-runs candidate validation,
|
||||||
then fetches and checks again before creating an explicitly unsigned lightweight
|
then fetches and checks again before creating an explicitly unsigned lightweight
|
||||||
tag for the originally recorded commit. It refuses dirty, divergent, changed,
|
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
|
```text
|
||||||
refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH
|
refs/tags/vMAJOR.MINOR.PATCH:refs/tags/vMAJOR.MINOR.PATCH
|
||||||
```
|
```
|
||||||
|
|
||||||
It never commits changes, pushes `main`, force-pushes, moves a tag, or pushes
|
It never commits changes, pushes `main`, force-pushes, moves tags, or pushes all
|
||||||
all tags. A successful push of that exact ref completes the release command;
|
tags. Successful publication of that ref completes the command; it prints the
|
||||||
the command prints the tag and commit, then returns without waiting for CI,
|
tag and commit and returns without waiting for CI, querying Gitea, downloading
|
||||||
querying Gitea, downloading assets, or checking checksums.
|
assets, or checking checksums.
|
||||||
|
|
||||||
If a failure occurs before the tag is created, correct the candidate on `main`
|
## Failure handling
|
||||||
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
|
Before tag creation, correct the candidate on `main` and repeat validation.
|
||||||
blindly. Once the upstream tag has been pushed, it is immutable. Correct any
|
If a push fails after local tag creation, the local tag is retained for inspection.
|
||||||
defect or failed asynchronous publication with a new patch version, a new
|
Do not retry blindly or assume the remote received nothing: a connection failure
|
||||||
release note, and the complete procedure again.
|
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
|
## Optional asynchronous inspection
|
||||||
|
|
||||||
After a successful tag push, a human may later inspect the tag-triggered
|
A human may later inspect the tag-triggered Woodpecker job and Gitea release.
|
||||||
Woodpecker run and the corresponding Gitea release for binaries and checksums.
|
This is optional follow-up, never part of the automated releaser's completion
|
||||||
This is optional follow-up only. Automated releasers must not wait for, poll,
|
criteria. Do not wait for or poll CI/Gitea from the release command.
|
||||||
or treat CI/Gitea completion as a condition of the successful tag push.
|
|
||||||
|
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
|
Do not add compatibility code to make intermediate states look like a supported
|
||||||
release.
|
release.
|
||||||
|
|
||||||
Before each stage, read `AGENTS.md`, `docs/development.md`, and all three policies
|
Before each stage, read `AGENTS.md`, `docs/development.md`, and all policies
|
||||||
under `docs/policy/`: architecture, documentation, and testing. Read this plan's
|
under `docs/policy/`: agents, architecture, documentation, testing, and release.
|
||||||
selected design and that stage's preparation. Use Go 1.26 and graph-first code
|
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
|
discovery; inspect current files when graph results are incomplete. Preserve
|
||||||
unrelated changes. Test at behavioral owners rather than replicating every case
|
unrelated changes. Test at behavioral owners rather than replicating every case
|
||||||
across configuration, adapter, stage, and command tests.
|
across configuration, adapter, stage, and command tests.
|
||||||
|
|||||||
Reference in New Issue
Block a user