diff --git a/src/docs/Capabilities/release-management/design.md b/src/docs/Capabilities/release-management/design.md
index 1466cc6..cd2ca1f 100644
--- a/src/docs/Capabilities/release-management/design.md
+++ b/src/docs/Capabilities/release-management/design.md
@@ -1,6 +1,6 @@
---
title: Design
-description: How release management is built — effective defaults, owned overrides, source-bound notes, and build-once publication.
+description: How release management is built — effective defaults, owned overrides, keyed release types, source-bound notes, and build-once publication.
---
# Release Management — Design
@@ -8,7 +8,7 @@ description: How release management is built — effective defaults, owned overr
The behavior in the [spec](spec.md) is delivered by shared release mechanics,
through a reusable workflow or a native producer pipeline. A repository's
effective release pipeline establishes which target routes are managed. The
-optional `.github/release.config.yml` file refines those settings; it does not
+optional `.github/release.settings.yml` file refines those settings; it does not
create a release pipeline, and its absence does not opt a managed route out.
Documented defaults make a managed route usable without per-PR bump labels;
repository settings, supported caller inputs, and owned labels provide overrides.
@@ -21,7 +21,7 @@ immutable output that another system consumes by version.
- When a shared workflow or native producer pipeline delivers that release
behavior, evaluate its release decision and require the pre-merge check. This
- remains true when `.github/release.config.yml` is absent or the route does not
+ remains true when `.github/release.settings.yml` is absent or the route does not
call a named shared workflow.
- When the route has no versioned release behavior, Release Management does not
apply. Omit the `Release decisions` block and every `release:*` label,
@@ -40,29 +40,41 @@ a successful skip.
## Branching model
-A **release branch** is any branch configured as a release target, each with a
-**release type** — `stable` or `prerelease`.
-
-- **Single branch (zero-config).** One release branch (the default branch)
- produces stable releases. Prereleases are opt-in via a PR label.
-- **Multi-branch.** `dev` (prerelease) collects PRs and publishes a prerelease
- on every merge; `main` (stable) receives `dev`. Merging `dev → main` computes
- the stable version from the **latest stable release** plus the merge PR's
- resolved bump — the prerelease counter does not carry over.
-- **One production authority.** At most one branch is `release-type: stable`;
- every other release branch is `prerelease`. The single stable branch
- (typically `main`) owns the production version — a prerelease branch can never
- cut a stable release.
+A **release branch** is a branch assigned to one key in the `ReleaseType`
+configuration object. The fixed keys are `Stable`, `Prerelease`, and
+`ReleaseCandidate`; each key owns the properties for that release type,
+including its `Branch`.
+
+- **Single branch (zero-config).** `ReleaseType.Stable.Branch` always resolves:
+ when `ReleaseType` or its `Stable` key is omitted, it uses the default branch.
+ `Prerelease` and `ReleaseCandidate` are optional. Prereleases remain available
+ from an open pull request through the mode label.
+- **Multi-branch.** A full promotion path uses
+ `ReleaseType.Prerelease.Branch` for early testing,
+ `ReleaseType.ReleaseCandidate.Branch` for the promotable candidate, and
+ `ReleaseType.Stable.Branch` for production. Each configured branch publishes
+ only its keyed release type. Promotion to `ReleaseType.Stable.Branch` computes
+ from the latest stable release plus the merge pull request's resolved bump;
+ prerelease and release-candidate counters do not carry over.
+- **One branch per type.** Each release-type key has at most one `Branch`, and
+ the same branch MUST NOT appear under more than one key. Unknown keys and
+ duplicate branch assignments are rejected.
+- **One production authority.** `Stable.Branch` is the only branch that cuts a
+ stable release. A prerelease or release-candidate branch can never publish the
+ production version.
- **Bundled releases.** A **staging branch** collects feature PRs; merging it to
a release branch produces **exactly one** release for all bundled changes.
```yaml
-# .github/release.config.yml
-release-branches:
- - branch: main
- release-type: stable
- - branch: dev
- release-type: prerelease
+# .github/release.settings.yml
+DefaultBump: patch
+ReleaseType:
+ Stable:
+ Branch: main
+ Prerelease:
+ Branch: dev
+ ReleaseCandidate:
+ Branch: rc
```
## The pipeline
@@ -107,7 +119,7 @@ that supplied each decision before Build.
Follow [Smart defaults, local overrides](../../Ways-of-Working/Principles/Software-Design.md#smart-defaults-local-overrides):
shared defaults are overridden by repository settings in the optional
-`.github/release.config.yml`, then by explicitly supplied supported caller
+`.github/release.settings.yml`, then by explicitly supplied supported caller
inputs for that invocation. Omitted caller inputs preserve repository settings;
they do not overwrite them with an input's default. The implementing workflow
or action documents its exact supported caller surface and validates it through
@@ -121,13 +133,13 @@ even when a narrower override or bump label exists.
| Setting | Shared default | Repository override | Supported caller override |
| --- | --- | --- | --- |
-| `DefaultBump` | `patch` | `DefaultBump` in `.github/release.config.yml` | Explicitly supplied caller override supported and documented by the invoked producer for this setting. |
+| `DefaultBump` | `patch` | `DefaultBump` in `.github/release.settings.yml` | Explicitly supplied caller override supported and documented by the invoked producer for this setting. |
For example, a repository can select minor as its normal level without requiring
a minor label on every publishing PR:
```yaml
-# .github/release.config.yml
+# .github/release.settings.yml
DefaultBump: minor
```
@@ -240,23 +252,26 @@ happen. Retrying failed validation or publication is not an ad hoc release
either: rerun the existing release with the same artifact and version under the
[recovery rule](#the-pipeline).
-## Prereleases
-
-- **Branch-level** — a prerelease-type branch publishes on every push, using the
- branch name as the identifier: `v1.3.0-dev.1`, `v1.3.0-dev.2`, …
-- **PR-level** — `release:prerelease` with a resolved explicit or default bump publishes
- `v-.`: `base` is the next version from that bump,
- `identifier` is the normalized branch name, and `counter`
- auto-increments per push.
+## Prereleases and release candidates
+
+- **Prerelease branch** — `ReleaseType.Prerelease.Branch` publishes on every
+ push, using the branch name as the identifier: `v1.3.0-dev.1`,
+ `v1.3.0-dev.2`, …
+- **Release-candidate branch** — `ReleaseType.ReleaseCandidate.Branch` publishes
+ `v1.3.0-rc.1`, `v1.3.0-rc.2`, … and never promotes one to latest.
+- **PR-level** — `release:prerelease` on an open PR publishes
+ `v-.`: `base` is the next version from one explicit
+ owned bump label when present, otherwise from the resolved `DefaultBump`;
+ `identifier` is the normalized branch name, and `counter` auto-increments per
+ push.
- Artifact-specific conventions replace the SemVer suffix where they exist
- (`-alpha.N` for npm, `.devN` for Python). Release candidates use `-rc.N`,
- auto-incrementing.
+ (`-alpha.N` for npm, `.devN` for Python).
- **Cleanup** deletes prerelease tags, releases, and artifacts after the PR
closes (configurable); stable releases are never touched.
## Path filtering
-When present, `.github/release.config.yml` declares `release-paths` as ordered
+When present, `.github/release.settings.yml` declares `release-paths` as ordered
include/exclude globs (excludes win). On an invoked route, the workflow
**always runs** so validation executes on every merge; only the release step is
skipped when no artifact-affecting path changed.
@@ -486,20 +501,20 @@ Serialisation is provided once by the reusable workflow so every repository
inherits it; the mechanism is the
[GitHub Actions standard](../../Coding-Standards/GitHub-Actions.md#concurrency).
The single-stable-branch rule above is what keeps the production version under
-one authority — the stable branch is the only ref that ever cuts a production
-release, and its runs are serialised like any other.
+one authority — `ReleaseType.Stable.Branch` is the only ref that ever cuts a
+production release, and its runs are serialised like any other.
## Configuration surface
| Surface | Where |
| --- | --- |
| Release Management applicability | effective target-route pipeline, including shared workflows and native producers |
-| Release branches + type | optional `.github/release.config.yml`; the default branch is stable when omitted |
+| Release types + branch mapping | `ReleaseType` in `.github/release.settings.yml` |
| Default bump and overrides | documented shared `DefaultBump: patch`, repository settings, then supported caller inputs |
| Explicit bump / prerelease / skip | `release:` PR label on an invoked route |
| Pre-merge decision validation | named PR check required by the branch ruleset or protection |
| Optional ad hoc release | `workflow_dispatch` inputs |
-| Path filter | `.github/release.config.yml` |
+| Path filter | `.github/release.settings.yml` |
| Prerelease cleanup toggle | release config / workflow input |
| Publishing targets | reusable-workflow input + GitHub environment; see [Publishing Targets](design-publishing-targets.md) |
diff --git a/src/docs/Capabilities/release-management/index.md b/src/docs/Capabilities/release-management/index.md
index 0a99ebb..aa9b991 100644
--- a/src/docs/Capabilities/release-management/index.md
+++ b/src/docs/Capabilities/release-management/index.md
@@ -7,17 +7,17 @@ description: How a source change becomes a versioned, immutable artifact, driven
Turning a merged change into a versioned, immutable artifact — a container
image, a GitHub Action or reusable workflow, a language package, a Terraform
-module — paired with a GitHub Release and a git tag, normally driven by
-pull-request labels. An implementation may add a GitHub-native ad hoc release
-path when its product needs one. No release CLI, no hand-edited version file,
-no tagging ritual.
+module — paired with a GitHub Release and a git tag, driven by a configured
+default and pull-request label overrides. An implementation may add a
+GitHub-native ad hoc release path when its product needs one. No release CLI,
+no hand-edited version file, no tagging ritual.
| Page | Description |
| --- | --- |
| [Spec](spec.md) | Requirements for release management — validated defaults, reviewed overrides, immutable artifacts, and complete consumer release records. |
-| [Design](design.md) | How release management is built — effective defaults, owned overrides, source-bound notes, and build-once publication. |
+| [Design](design.md) | How release management is built — effective defaults, owned overrides, keyed release types, source-bound notes, and build-once publication. |
| [Publishing Targets](design-publishing-targets.md) | The contract every publishing destination documents, with GitHub Releases as the reference target. |
diff --git a/src/docs/Capabilities/release-management/spec.md b/src/docs/Capabilities/release-management/spec.md
index 5ef9a80..a586440 100644
--- a/src/docs/Capabilities/release-management/spec.md
+++ b/src/docs/Capabilities/release-management/spec.md
@@ -16,7 +16,7 @@ release CLI, a hand-edited version file, or a tagging convention.
A target route participates when its effective pipeline produces a versioned,
immutable output consumed by version. This includes a shared Release Management
workflow and a native producer pipeline; the contract is not conditional on one
-implementation's name. The optional `.github/release.config.yml` file refines a
+implementation's name. The optional `.github/release.settings.yml` file refines a
managed route's settings but does not create a release pipeline, and its absence
does not opt a managed route out.
@@ -41,20 +41,21 @@ If no, there is nothing to release and the pull request carries neither the
## Requirements
- **Semantic versioning.** Versions follow [SemVer 2.0.0](https://semver.org/) (`vMAJOR.MINOR.PATCH`), derived automatically — never written by hand.
-- **Release behavior determines applicability.** Release Management MUST evaluate every pull request targeting a managed release route, including native producer routes and routes without `.github/release.config.yml`. A route without versioned release behavior MUST NOT require, apply, or report the `Release decisions` block or any `release:*` label.
+- **Release behavior determines applicability.** Release Management MUST evaluate every pull request targeting a managed release route, including native producer routes and routes without `.github/release.settings.yml`. A route without versioned release behavior MUST NOT require, apply, or report the `Release decisions` block or any `release:*` label.
- **Producer compatibility is verified, not inferred.** Authors MUST verify the effective producer revision's settings and owned-label mapping. A differing released interface MUST have a verified adapter or producer/configuration migration before the canonical signals are used. Unsupported signals MUST block finalization and required decision validation, not become ignored skip requests or an excuse to classify a managed route as unmanaged. The producer's PR/release record owns its exact adoption actions.
- **Settings have documented defaults and supported overrides.** Release automation MUST document its setting names, accepted values, shared defaults, and supported caller overrides. Repository settings MUST override shared defaults; explicitly supplied supported caller inputs MUST override repository settings for that invocation. Unknown settings and invalid supplied values MUST fail even when a narrower override or explicit bump label exists. Omission MUST inherit a documented default rather than require configuration to become usable.
-- **A resolved PR release decision.** `DefaultBump` accepts exactly `patch`, `minor`, or `major` and has the shared default `patch`. Multiple owned bump labels, or `release:skip` combined with another owned release label, MUST fail. A valid `release:skip` MUST select no release without resolving a bump. For publishing decisions, one owned `release:patch`, `release:minor`, or `release:major` label MUST take precedence over the valid effective default; without a bump label, that default MUST supply the level without requiring a per-PR bump label. If neither source resolves a valid level, automation MUST fail with an actionable decision error; it MUST NOT recover from invalid input by selecting patch. `release:prerelease` MAY use either the explicit or default bump; the mode alone does not supply a level. Bare or unrelated labels MUST be ignored. Conventional commit messages are **not** required.
-- **A release per merge.** One eligible merged PR with a resolved bump to an invoked release route is one release, and the PR review gate is the release gate. `release:skip` validates without publishing. This pull-request path is the required release interface.
-- **Decision validation blocks merge.** Every PR targeting an invoked release route MUST receive a named release-decision CI check required by the branch ruleset or protection. Missing decisions, invalid defaults, and conflicting owned labels MUST fail that check before merge, not only during publication. Source, release-label, and release-settings changes MUST re-evaluate the decision. A failing, pending, or absent required result MUST block both manual and automated merge; a log message, warning, or skipped validator is not enforcement. A valid `release:skip` MUST report a successful no-release decision, not skip the check.
+- **A resolved PR release decision.** `DefaultBump` accepts exactly `patch`, `minor`, or `major` and has the shared default `patch`. With no owned bump label, automation MUST use the valid effective default without requiring a per-PR bump label. Exactly one of `release:patch`, `release:minor`, or `release:major` MUST override that default. `release:prerelease` uses the resolved bump; mode alone supplies no level. Multiple owned bump labels, or `release:skip` with another owned release label, MUST fail. A valid skip MUST suppress publication without resolving a bump. If no valid level resolves, automation MUST fail rather than select a fallback. Bare and unrelated labels MUST be ignored. Conventional commit messages are **not** required.
+- **A release per eligible merge.** One artifact-affecting merged PR with a resolved bump to a managed release route is one release, and the PR review gate is the release gate. The bump comes from one explicit owned bump label or the valid effective `DefaultBump`. `release:skip` and out-of-scope changes validate without publishing. This pull-request path is the required release interface.
- **Ad hoc release is optional.** An implementation MAY expose `workflow_dispatch` when its product needs an ad hoc release outside the merge flow; implementations are not required to support it. A dispatch MUST require an explicit release decision and release-note context, and MUST use the same version, build, validation, immutability, and publication controls as a merged pull request. A direct push MUST NOT be an ad hoc release interface, and an empty pull request MUST NOT be created solely to trigger a release.
- **Version before build.** The version MUST be resolved before the artifact is built, so the version is part of the artifact's identity rather than a label attached afterwards.
- **Build once.** The artifact MUST be built exactly once and MUST NOT be altered after it is built. The same bytes flow through validation and publishing. Rebuilding to publish means the tested artifact and the published artifact are different artifacts.
-- **Stable and prerelease.** Every release is either **stable** (the latest version to adopt) or a **prerelease** (testable, not promoted to latest). A prerelease MUST be obtainable from an open pull request carrying `release:prerelease`, using its explicit or default bump, and/or from a prerelease branch. A configured release candidate is a prerelease with its own candidate series, not an additional owned release label.
+- **Stable and prerelease.** Every release is either **stable** (the latest version to adopt) or a **prerelease** (testable, not promoted to latest). A configured release candidate is a prerelease with its own candidate series, not an additional owned release label.
+- **Release types.** Every release branch MUST produce exactly one type: **stable** (the latest version to adopt), **prerelease** (early testable output), or **release candidate** (promotable output that is not latest). A branch MUST NOT produce more than one type. A prerelease MUST also be obtainable from an open pull request carrying `release:prerelease`, using its explicit owned bump label or the resolved `DefaultBump`.
+- **Decision validation blocks merge.** Every PR targeting a managed release route MUST receive a named release-decision CI check required by the branch ruleset or protection. Missing decisions, invalid defaults, and conflicting owned labels MUST fail that check before merge, not only during publication. Source, release labels, release settings, supported caller inputs, and effective-pipeline changes MUST re-evaluate the decision. A failing, pending, or absent required result MUST block both manual and automated merge; a log message, warning, or skipped validator is not enforcement. A valid `release:skip` MUST report a successful no-release decision, not skip the check.
- **Serialised releases.** Only one release process runs against a given version of the codebase (the same ref) at a time. A release mutates shared, version-anchored state — the tag, the version counter, the published artifact — so overlapping runs on the same ref MUST NOT race, and an in-flight release is never interrupted.
- **A single production authority.** Exactly one branch is in charge of the production (stable) version, so consumers get one unambiguous latest stable release and two branches can never publish competing production releases.
- **Notes from the contributor's own words.** The GitHub Release name is the version; its body MUST preserve the release-bound pull request title and complete description, or equivalent complete release-note context for an optional ad hoc dispatch. The authored record follows [PR Format](../../Ways-of-Working/PR-Format.md#write-the-description); classified results and their section-scoped technical details and related references MUST NOT be omitted or summarized away.
-- **Only artifact-affecting changes release.** On an invoked release route, a change that does not affect the delivered artifact or its supported consumer contracts MUST carry `release:skip` and MUST NOT produce a release — though validation still runs on every merge. Documentation and internal CI configuration qualify only when they meet that condition. An Action or reusable workflow is itself a product for its callers; its interface and behavior MUST NOT be dismissed as internal tooling because of the file path.
+- **Only artifact-affecting changes release.** On a managed release route, a change that does not affect the delivered artifact or its supported consumer contracts MUST carry `release:skip` and MUST NOT produce a release — though validation still runs on every merge. Unmanaged routes omit that label and all release metadata. Documentation and internal CI configuration qualify only when they meet the artifact-impact condition. An Action or reusable workflow is itself a product for its callers; its interface and behavior MUST NOT be dismissed as internal tooling because of the file path.
- **Immutable references.** Consumers pin to the most immutable reference available — a container digest or a commit SHA — never a mutable tag.
- **Publish through a target contract.** Every publishing destination is reached through the same [publishing-target contract](design-publishing-targets.md), so the release process stays one process regardless of how many destinations a repository has. Adding a destination supplies a contract and a publish step; it MUST NOT change the release process.
- **All-or-nothing across targets.** Where a repository publishes one artifact to more than one destination, a version MUST NOT end up present on some destinations and absent from others. Partial publication is a failure, reported as one, and resumed by completing the remaining destinations with the same immutable artifact and version.
@@ -87,14 +88,14 @@ Because versions are semantic, immutable, and published once, a consumer can ado
## Success criteria
-- Merging an eligible PR with an explicit or configured bump produces a GitHub Release, a git tag, and (where one exists) a published artifact, with no manual step.
-- A pull request targeting a managed release route, including a native producer route, is evaluated even when `.github/release.config.yml` is absent; an unmanaged route carries no release decision block, label, or check.
-- With no repository setting, caller override, or bump label, a publishing PR resolves the documented patch default. A repository default and supported caller override resolve in that order, and an explicit owned bump label overrides the valid effective default.
-- The resolver records the effective value and its source. Invalid supplied settings and conflicting owned labels block merge even when another input would supply a valid level; no success-shaped fallback occurs.
-- Removing a bump override re-evaluates the PR check against the effective default; changing source, settings, or route inputs also re-evaluates it. A prior result does not validate different inputs.
-- An open pull request carrying `release:prerelease` and an explicit or default bump publishes a prerelease without promoting it to latest.
+- Merging an eligible artifact-affecting PR with a resolved bump to a managed release route produces a GitHub Release, a git tag, and (where one exists) a published artifact with no manual step. Skip and out-of-scope changes validate without publishing.
+- A publishing PR inherits the documented patch default when no repository setting, supported caller override, or owned bump label is supplied. Repository settings, supported caller inputs, and an explicit owned bump label override it in that order, with the chosen source recorded.
+- Invalid supplied settings and conflicting owned labels fail even when another input supplies a valid level. Removing a bump override re-evaluates the required check against the effective default; source, settings, and caller changes invalidate prior evidence.
+- A managed native producer route and a route without `.github/release.settings.yml` still receive release-decision validation; an unmanaged route carries no release metadata or labels.
+- An open pull request carrying `release:prerelease` publishes a prerelease without promoting it to latest, using one explicit owned bump label when present and the resolved `DefaultBump` otherwise.
+- A configured prerelease branch publishes prerelease versions, and a configured release-candidate branch publishes `-rc.N` versions; neither promotes an artifact to latest.
- The artifact that consumers download is byte-identical to the artifact that passed validation.
-- On an invoked release route, a documentation-only merge carrying `release:skip` produces no new version but still runs its CI checks.
+- On a managed route, a merge outside the artifact/consumer scope carrying `release:skip` produces no version but still runs its checks; an unmanaged route omits release labels and metadata entirely.
- Two release runs for the same ref never overlap; the second waits for the first to finish rather than racing it.
- Only the single production branch ever publishes a stable release.
- A version that reaches one publishing target reaches all of them, or the release is reported as failed.
diff --git a/src/docs/Capabilities/vscode-extension-framework/design.md b/src/docs/Capabilities/vscode-extension-framework/design.md
index ab8e226..684647e 100644
--- a/src/docs/Capabilities/vscode-extension-framework/design.md
+++ b/src/docs/Capabilities/vscode-extension-framework/design.md
@@ -201,10 +201,10 @@ Every external Action is pinned to a commit SHA; organization- or initiative-own
| --- | --- |
| Adoption (opt-in) | a short caller workflow that calls the reusable workflow |
| Host + OS matrix, marketplace toggle, extras | `.github/vscode-extension.yml` |
-| Explicit bump / prerelease / skip | owned pull-request label |
| Default bump and overrides | shared `DefaultBump: patch`, repository settings, and supported caller inputs |
+| Explicit bump / prerelease / skip | owned pull-request label |
| Pre-merge decision validation | version check required by the branch ruleset or protection |
-| Release branches + path filter | `.github/release.config.yml` ([Release Management](../release-management/design.md)) |
+| Release types + branch mapping + path filter | `.github/release.settings.yml` ([Release Management](../release-management/design.md)) |
| Marketplace publish tokens | a GitHub environment's secrets |
| Extension manifest (`engines.vscode`, `contributes`, activation) | `package.json` |
@@ -218,7 +218,7 @@ The template repository lays down the whole shape, mirroring
`contributes`, `activationEvents`, and `main` pointing at the bundle.
- the bundler config, `tsconfig.json`, and `.vscodeignore`.
- `install/` — the hosted one-liner install scripts.
-- `.github/` — the caller workflow, `vscode-extension.yml`, `release.config.yml`,
+- `.github/` — the caller workflow, `vscode-extension.yml`, `release.settings.yml`,
and `dependabot.yml`.
## Where this connects
diff --git a/src/docs/Ways-of-Working/Automation-Labels.md b/src/docs/Ways-of-Working/Automation-Labels.md
index fd3b443..64f4b63 100644
--- a/src/docs/Ways-of-Working/Automation-Labels.md
+++ b/src/docs/Ways-of-Working/Automation-Labels.md
@@ -60,7 +60,7 @@ This set applies only when the pull request's target route invokes Release
Management, including through a native producer pipeline. An unmanaged route
does not apply or report any
`release:*` label, including `release:skip`. The optional
-`.github/release.config.yml` file refines an invocation; its absence alone does
+`.github/release.settings.yml` file refines an invocation; its absence alone does
not determine whether the route invokes the capability.
These labels are read by
diff --git a/src/docs/Ways-of-Working/PR-Format.md b/src/docs/Ways-of-Working/PR-Format.md
index 556dd40..c741204 100644
--- a/src/docs/Ways-of-Working/PR-Format.md
+++ b/src/docs/Ways-of-Working/PR-Format.md
@@ -167,7 +167,7 @@ target route. Inspect the effective pipeline and its inputs, including native
producer pipelines that publish versioned artifacts without calling a named
shared workflow. The [applicability contract](../Capabilities/release-management/design.md#applicability)
is about the route's release behavior, not one implementation. The optional
-`.github/release.config.yml` file refines the route's settings; its absence alone
+`.github/release.settings.yml` file refines the route's settings; its absence alone
does not prove that release management is absent.
Verify the immutable producer revision's supported settings and owned-label
@@ -411,7 +411,7 @@ from the actual base.
When the target route does not invoke Release Management, omit this block and
all `release:*` labels. Do not add `release:skip` merely because the repository
-has no `.github/release.config.yml`.
+has no `.github/release.settings.yml`.
### Assemble the body
diff --git a/tests/ReleaseSettingsDocumentation.Tests.ps1 b/tests/ReleaseSettingsDocumentation.Tests.ps1
new file mode 100644
index 0000000..69e06c4
--- /dev/null
+++ b/tests/ReleaseSettingsDocumentation.Tests.ps1
@@ -0,0 +1,28 @@
+#Requires -Modules @{ ModuleName = 'Pester'; ModuleVersion = '6.0.0'; MaximumVersion = '6.*' }
+
+$ErrorActionPreference = 'Stop'
+
+$releaseDocuments = @(
+ @{ Document = 'Capabilities\release-management\design.md' }
+ @{ Document = 'Capabilities\release-management\spec.md' }
+ @{ Document = 'Capabilities\vscode-extension-framework\design.md' }
+ @{ Document = 'Ways-of-Working\Automation-Labels.md' }
+ @{ Document = 'Ways-of-Working\PR-Format.md' }
+)
+
+Describe 'Release settings documentation' {
+ BeforeAll {
+ $repositoryRoot = Split-Path -Path $PSScriptRoot -Parent
+ $script:documentationRoot = Join-Path -Path $repositoryRoot -ChildPath 'src\docs'
+ }
+
+ It ' uses the canonical repository release settings filename' -ForEach $releaseDocuments {
+ $path = Join-Path -Path $documentationRoot -ChildPath $Document
+ $content = Get-Content -LiteralPath $path -Raw
+
+ $content -cmatch '\.github/release\.settings\.yml\b' |
+ Should -BeTrue -Because 'the release settings stay in the .github directory'
+ $content -notmatch '\brelease\.config\.yml\b' |
+ Should -BeTrue -Because 'active guidance no longer uses the previous filename'
+ }
+}