Align repository policies with shared standards

This commit is contained in:
2026-09-25 15:11:08 +00:00
parent 17cef0700a
commit 625e6edfd7
8 changed files with 465 additions and 60 deletions

View File

@@ -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
View 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.

View File

@@ -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.

View File

@@ -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
View 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.

View File

@@ -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**.

View File

@@ -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.

View File

@@ -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.