From 4c43b153fd7658267b567bfac40557e08b16b00e Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 13:25:54 +0100 Subject: [PATCH 1/3] Clarify release publication and recovery hazards --- src/docs/Capabilities/release-management/spec.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/docs/Capabilities/release-management/spec.md b/src/docs/Capabilities/release-management/spec.md index 34b89f1..a184282 100644 --- a/src/docs/Capabilities/release-management/spec.md +++ b/src/docs/Capabilities/release-management/spec.md @@ -21,17 +21,17 @@ update policy that matches their trust boundary. ## Problem and importance A tag or successful workflow run is not enough to prove that a release completed. -Publication can expose one destination before another fails, mutable pull-request -metadata can change before a retry, and a later commit can reach the stable branch -while an earlier artifact is still incomplete. Recomputing from current state can -then publish different bytes under a reserved version, omit accumulated changes -from the notes, or advertise an incomplete release as current. +Publication can expose one destination before another fails. +Mutable pull-request metadata can change before a retry. +A later commit can reach the stable branch while an earlier artifact is still incomplete. +Recomputing from current state can then publish different bytes under a reserved version. +It can also omit accumulated changes from the notes or advertise an incomplete release as current. Release management makes the release intent durable. It fixes the approved source, decision, version, notes, artifact identity, required destinations, and stage -progress, then advances that intent safely through publication. This gives -contributors a predictable release path, operators a recoverable process, and -consumers an accurate version and update contract. +progress. It then advances that intent safely through publication. +This gives contributors a predictable release path, operators a recoverable process, +and consumers an accurate version and update contract. ## Users and jobs From 76027eeab7041884beb332c7606a19cb64196038 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 13:28:42 +0100 Subject: [PATCH 2/3] Clarify release lifecycle and moved-tag guidance --- .../accept-moved-release-tags.md | 17 +++---- .../design-publishing-targets.md | 20 ++++---- .../Capabilities/release-management/design.md | 47 ++++++++++--------- .../Capabilities/release-management/index.md | 11 +++-- .../Capabilities/release-management/spec.md | 8 ++-- 5 files changed, 54 insertions(+), 49 deletions(-) diff --git a/src/docs/Capabilities/release-management/accept-moved-release-tags.md b/src/docs/Capabilities/release-management/accept-moved-release-tags.md index 92298d7..5179c87 100644 --- a/src/docs/Capabilities/release-management/accept-moved-release-tags.md +++ b/src/docs/Capabilities/release-management/accept-moved-release-tags.md @@ -5,9 +5,9 @@ description: Refresh an owned moving release alias locally and configure Git to # Accept moved release tags -Use this guide when an MSX-owned producer intentionally publishes a moving Git -tag such as `v3` or `v3.4` and your local clone still resolves it to an older -release. +Use this guide for an MSX-owned producer's intentionally moving Git tag, such as +`v3` or `v3.4`. Refresh the tag when your local clone still resolves it to an +older release. Do not use this procedure for exact version tags such as `v3.4.2`. Exact version tags are immutable. A moved exact tag is a producer integrity incident, not a @@ -43,10 +43,11 @@ git bundle create owned-tags-backup.bundle --tags git bundle verify owned-tags-backup.bundle ``` -Keep that backup private and outside checked-in paths. Pruning removes local tags -that do not exist on the selected remote, and force permits that remote's tag -values to replace local values. Confirm that `origin` is the intended trusted -producer and that no exact-version-tag integrity incident is being normalized. +Keep that backup private and outside checked-in paths. +Pruning removes local tags that do not exist on the selected remote. +Force permits that remote's tag values to replace local values. +Confirm that `origin` is the intended trusted producer. +Do not use this procedure to accept a moved exact version tag. ```bash git fetch --tags --force --prune --prune-tags origin @@ -54,7 +55,7 @@ git fetch --tags --force --prune --prune-tags origin This refreshes moved aliases and removes tags deleted from the configured `origin` remote. Review the fetch output before building or resolving a -dependency; never let an implicit upstream choose the source of this refresh. +dependency. Never let an implicit upstream choose the source of this refresh. ## Keep owned aliases current diff --git a/src/docs/Capabilities/release-management/design-publishing-targets.md b/src/docs/Capabilities/release-management/design-publishing-targets.md index 9c94a25..b9efa58 100644 --- a/src/docs/Capabilities/release-management/design-publishing-targets.md +++ b/src/docs/Capabilities/release-management/design-publishing-targets.md @@ -57,13 +57,13 @@ Two rules apply to every row: version. - **Completion is an outcome, not a claim of transactional publication.** One target may expose content before another fails. Durable per-target progress - keeps the release incomplete until all required targets succeed, then lets a - retry resume safely. + keeps the release incomplete until all required targets succeed. + A retry uses that progress to resume safely. ## GitHub Releases GitHub Releases is the reference target and the cross-target join point. Every -repository governed by this capability creates a GitHub Release; a repository +repository governed by this capability creates a GitHub Release. A repository with no external artifact publishes there only. External target coordinates and evidence are linked from the same release record. @@ -96,8 +96,8 @@ frozen release intent. Repositories enable GitHub's immutable-release protection where the platform supports it. Verify the effective repository setting and producer controls from read-back evidence rather than assuming they exist because this contract -describes them. Policy alone is not proof of platform enforcement; missing -controls are conformance gaps to record and resolve. +describes them. Policy alone is not proof of platform enforcement. +Missing controls are conformance gaps to record and resolve. ### GitHub withdrawal @@ -151,7 +151,7 @@ into its native package coordinate. For example, canonical `2.5.0-alpha` maps to `ModuleVersion = '2.5.0'` and `PrivateData.PSData.Prerelease = 'alpha'`, not `ModuleVersion = '2.5.0-alpha'`. The adapter validates the label against the selected publishing client's actual -syntax; dotted or build-metadata forms are not assumed to be accepted. A +syntax. Dotted or build-metadata forms are not assumed to be accepted. A non-preserving conversion requires an explicit collision-free, ordering-aware mapping or fails as unsupported before publication. Record both canonical and native identities. See [PowerShell prerelease module fields](https://learn.microsoft.com/en-us/powershell/gallery/concepts/module-prerelease-support). @@ -160,8 +160,8 @@ native identities. See [PowerShell prerelease module fields](https://learn.micro A published module version is immutable. Retrying succeeds only when the existing listing and package hash identify the recorded artifact. The gallery -supports unlisting rather than reclaiming a version; existing consumers and -caches can still hold it, and the coordinate remains permanently reserved. +supports unlisting rather than reclaiming a version. Existing consumers and +caches can still hold it. The coordinate remains permanently reserved. ### PowerShell Gallery aliases and constraints @@ -222,7 +222,7 @@ mapping plus an independently invented prerelease mapping. An odd-minor convention is valid only when the declared stable mapping reserves that space and the series/counter allocation is proven collision-free across every supported canonical identity. Record canonical and native versions -together; an unsupported mapping or coordinate collision blocks publication. +together. An unsupported mapping or coordinate collision blocks publication. The [owning framework's mapping contract](../vscode-extension-framework/design.md#marketplace-version-mapping) controls that conversion, while the immutable GitHub VSIX install path remains available without Marketplace support. @@ -272,7 +272,7 @@ permitted bounded update selection resolves the eligible version outside that field and can retain its digest without a moving alias. A corresponding controlled alias is required only when no other permitted resolver supplies the requested bound. That alias must satisfy the consumer's trust boundary and -artifact-specific pinning standard; an unsupported bound fails rather than +artifact-specific pinning standard. An unsupported bound fails rather than widening silently. ### Container registry release record diff --git a/src/docs/Capabilities/release-management/design.md b/src/docs/Capabilities/release-management/design.md index 23d25ad..b97eaf2 100644 --- a/src/docs/Capabilities/release-management/design.md +++ b/src/docs/Capabilities/release-management/design.md @@ -7,7 +7,7 @@ description: Durable release intents, lifecycle transitions, recovery, withdrawa This page realizes the [release-management specification](spec.md) through shared, GitHub-native release mechanics, including native producer pipelines. -It defines the durable lifecycle and input contract; the immutable producer +It defines the durable lifecycle and input contract. The immutable producer revision's documented interface and verified behavior establish conformance. Documentation alone does not make a lifecycle control or setting available. @@ -15,7 +15,7 @@ Documentation alone does not make a lifecycle control or setting available. 1. **The release intent is authoritative.** Tags, releases, workflow runs, and destination listings are observations that must agree with durable state. -2. **Resolve once, then resume.** A retry continues frozen work; it never turns +2. **Resolve once, then resume.** A retry continues frozen work. It never turns current repository metadata into a different release under the same identity. 3. **Build once.** Verification and every destination receive the same retained bytes. @@ -32,7 +32,7 @@ The effective pipeline establishes whether the target route produces a versioned, immutable output consumed by version. Managed routes participate whether they use a shared workflow or a native producer pipeline, and whether `.github/release.settings.yml` exists. Unmanaged routes omit release metadata and -every `release:*` label; a Pages deployment alone is not a versioned release. +every `release:*` label. A Pages deployment alone is not a versioned release. ## Release authority and interfaces {#branching-model} @@ -42,7 +42,7 @@ routing types, not additional publication modes: prerelease and release-candidat routes both publish prereleases. The stable branch inherits the repository default branch when `ReleaseType` or -its `Stable` key is omitted; the other keys are optional. Validate unknown keys +its `Stable` key is omitted. The other keys are optional. Validate unknown keys and duplicate branch assignments after resolving inherited defaults. A branch cannot belong to two types, so assigning the inherited stable branch to `Prerelease` or `ReleaseCandidate` is invalid. @@ -64,7 +64,7 @@ fixed source is on that line can create a stable release. The merge path remains the default because it keeps the compatibility decision, consumer evidence, source review, and release-note source together. Manual -release exists for approved accumulated change, not as a way around review. +release requires review and covers approved accumulated change. The [Branching and Merging](../../Ways-of-Working/Branching-and-Merging.md) standard owns standing development-to-stable promotion. Release management @@ -79,8 +79,9 @@ identity makes duplicate delivery and retries idempotent. The identity includes the separately approved logical request, not only its source commit. Duplicate delivery or retry of that request loads the same frozen intent. A new corrective request requires distinct approval/request -identity and explicitly records which prior intent it replaces; it cannot reuse -the retired or withdrawn version, even when its reviewed source is unchanged. +identity. It explicitly records which prior intent it replaces. +It cannot reuse the retired or withdrawn version, even when its reviewed source +is unchanged. | Field | Frozen or progressive | Purpose | | --- | --- | --- | @@ -101,7 +102,7 @@ the retired or withdrawn version, even when its reviewed source is unchanged. | Announcement progress by destination | Progressive, append-only | Supports at-least-once delivery without republishing. | | Retirement or withdrawal evidence | Append-only | Preserves a terminal operator decision without rewriting history. | -The durable store can be implemented with any shared platform that provides +The durable store can use any shared platform that provides atomic writes, immutable history, and lookup by repository and intent. A workflow run summary is useful evidence but is not sufficient storage: runs can expire, retries use new run identifiers, and one run cannot safely coordinate @@ -257,9 +258,8 @@ first stable major release is `1.0.0`. The resolved version is persisted as a provisional reservation before Build. The reservation becomes permanent after the first successful build or any -external visibility. This separates safe coalescing of untouched work from the -non-negotiable rule that one visible or built coordinate always means one source -and one artifact. +external visibility. Untouched work can be coalesced safely. +A visible or built coordinate always identifies one source and one artifact. ### Resolve prereleases and release candidates @@ -301,7 +301,7 @@ prerelease channel, and a canonical prerelease cannot be represented as stable. ## Build, Verify, and Publish -The lifecycle retains the familiar four-stage pipeline: +The lifecycle uses four pipeline stages: ```text Resolve -> Build -> Verify -> Publish @@ -445,8 +445,8 @@ The complete captured title and body remain in the GitHub release record. Announcement delivery never extracts a subset of that record for publication. Each announcement destination has its own delivery record and idempotency key. -The sender records attempts and acknowledgements. If acknowledgement is missing, -it may resend the same logical message; receivers therefore observe +The sender records attempts and acknowledgments. If acknowledgment is missing, +it may resend the same logical message. Receivers therefore observe at-least-once delivery and should deduplicate by release identity. Announcement failure does not roll back a complete release and does not permit a @@ -520,12 +520,15 @@ The publication envelope augments, but does not rewrite, the authored note: - note snapshot provenance; and - completion, retirement, withdrawal, alias, and announcement events. -These bases can differ. With completed `1.4.2`, a permanently reserved retired -`1.5.0` attempt containing an approved minor change not published to the selected -artifact target still establishes minor as the minimum aggregate increment. -A reviewed minor resolves from the reserved base `1.5.0` to `1.6.0`, while that -target's consumer delta starts from published source `1.4.2`; patch is rejected -for the accumulated range. Freeze and publish both bases rather than presenting +These bases can differ. For example, `1.4.2` is complete and `1.5.0` is permanently +reserved by a retired attempt. The attempt contains an approved minor change +not published to the selected artifact target. That change still establishes +minor as the minimum aggregate increment. + +A reviewed minor resolves from the reserved base `1.5.0` to `1.6.0`. +The target's consumer delta starts from published source `1.4.2`. +Resolve rejects patch for the accumulated range. +Freeze and publish both bases rather than presenting the consumer-change source as proof of the calculation. For module notes, successful Gallery publication advances the consumer-change @@ -658,7 +661,7 @@ Lifecycle controls include independently disabled destinations; retained-artifact policy; and destination-specific native mapping. An implementation documents the exact keys and caller inputs it supports; this contract does not make unsupported controls available. Unknown fields and -values fail closed; repositories must not invent local release schema. +values fail closed. Repositories must not invent local release schema. Repositories choose policy. Shared automation owns resolution, durable state, SemVer calculation, artifact handoff, retry rules, target adapters, discovery, @@ -692,7 +695,7 @@ partial publication from completion. A separate manual pipeline would create a second version algorithm and weaker evidence path. Manual requests therefore change only the trigger and approval -source; they still Resolve, Build, Verify, and Publish one retained artifact. +source. They still Resolve, Build, Verify, and Publish one retained artifact. ### Announcements follow completion diff --git a/src/docs/Capabilities/release-management/index.md b/src/docs/Capabilities/release-management/index.md index 9d4fe8b..972da41 100644 --- a/src/docs/Capabilities/release-management/index.md +++ b/src/docs/Capabilities/release-management/index.md @@ -5,11 +5,12 @@ description: Durable version resolution, publication, recovery, withdrawal, and # Release Management -Turning approved source into a versioned, immutable artifact — a container -image, GitHub Action or reusable workflow, language package, Terraform module, -or documentation site — with durable release state and evidence. The ordinary -path starts from a reviewed merge; an approved manual request can release an -accumulated range. Both paths resolve once, build once, resume by recorded +Release management turns approved source into a versioned, immutable artifact +with durable release state and evidence. The artifact can be a container image, +GitHub Action or reusable workflow, language package, Terraform module, or +documentation site. The ordinary path starts from a reviewed merge. +An approved manual request can release an accumulated range. +Both paths resolve once, build once, resume by recorded phase, and advertise only completed eligible releases. Contributors express release intent through GitHub. Maintainers can recover, diff --git a/src/docs/Capabilities/release-management/spec.md b/src/docs/Capabilities/release-management/spec.md index a184282..3c24a59 100644 --- a/src/docs/Capabilities/release-management/spec.md +++ b/src/docs/Capabilities/release-management/spec.md @@ -8,10 +8,10 @@ description: Requirements for durable, recoverable, policy-driven releases and t ## Premise Release management turns approved source into a **versioned, immutable release** -that consumers can trust. A release is normally the result of merging reviewed -change, while a controlled manual request can release already-reviewed -accumulated change. Both paths use the same decision, build, verification, -publication, and evidence controls. +that consumers can trust. A release normally follows a reviewed merge. +A controlled manual request can release already-reviewed accumulated change. +Both paths use the same decision, build, verification, publication, and evidence +controls. The capability preserves enough durable state to finish an interrupted release without rebuilding or assigning its version to different content. Consumers can From 21c7794d00990954e059de2d7e82cbf48ebf2512 Mon Sep 17 00:00:00 2001 From: Marius Storhaug Date: Wed, 4 Nov 2026 13:31:52 +0100 Subject: [PATCH 3/3] Clarify downstream release qualification and handoffs --- .../downstream-release-propagation/design.md | 85 ++++++++++--------- .../downstream-release-propagation/index.md | 11 +-- .../downstream-release-propagation/spec.md | 31 ++++--- 3 files changed, 73 insertions(+), 54 deletions(-) diff --git a/src/docs/Capabilities/downstream-release-propagation/design.md b/src/docs/Capabilities/downstream-release-propagation/design.md index c2c7dd6..1cfde54 100644 --- a/src/docs/Capabilities/downstream-release-propagation/design.md +++ b/src/docs/Capabilities/downstream-release-propagation/design.md @@ -5,9 +5,9 @@ description: How downstream release propagation is built — an inline notificat # Downstream Release Propagation — Design -The notification runs in the **producer** when a release is cut. The notifier +The notification runs in the **producer** after a stable release. The notifier resolves the release coordinates, creates or reuses the dependent's Task or Bug, -and builds its self-contained brief. It first +and prepares its self-contained brief. It first [reconciles existing handoff state](#retry-and-handoff-recovery) rather than delegating again. For work still needing qualification, authoritative no-upgrade evidence terminates without engaging an agent. Otherwise, the configured @@ -42,10 +42,9 @@ flowchart TD ## Trigger model **The `GITHUB_TOKEN` constraint.** GitHub does not start new workflow runs from -events raised by the default `GITHUB_TOKEN` (an anti-recursion safeguard). So if -the producer publishes its release with `GITHUB_TOKEN` — the default — the -`release: published` event never fires, and a separate `on: release` workflow -never runs. +events raised by the default `GITHUB_TOKEN`. This prevents recursive workflow +runs. If the producer publishes its release with `GITHUB_TOKEN`, the +`release: published` event does not start a separate `on: release` workflow. | Release created by | `release: published` fires? | Trigger model | | --- | --- | --- | @@ -53,9 +52,10 @@ never runs. | A PAT | Yes | Either — a separate `on: release` workflow, or inline. | **Default to the inline model:** it works regardless of release identity and -keeps the release and its propagation in one observable run. Verify the identity -by which token the release step passes; if it is `GITHUB_TOKEN`, inline is -mandatory. Provide two entry points: the **release** stage (gated to stable +keeps the release and its propagation in one observable run. +Identify the token passed to the release step. +If it is `GITHUB_TOKEN`, inline is mandatory. +Provide two entry points: the **release** stage (gated to stable releases), and a **`workflow_dispatch`** taking the release tag, for backfill. Both resolve the published release record and validate its stable kind before fan-out or delivery-issue creation. A prerelease event is skipped; a backfill @@ -80,14 +80,16 @@ this capability. ## Agent prompt context -The prompt is the context handoff. Each embeds: an **action-oriented summary**; -the **exact target reference** the PR must produce -(`uses: org/@ # `, or the image tag/digest); the -**complete release notes** as evidence; and -**related-change context** — new or renamed config keys, new environment -variables or secrets, required infrastructure changes, migrations, changed -defaults, or breaking changes. It also links the producer-owned evidence sources -and [Consumer Upgrades](../../Ways-of-Working/Consumer-Upgrades.md). +The prompt carries an **action-oriented summary** and the **exact target +reference** that the PR must produce. +The reference is `uses: org/@ # ` or the image tag/digest. +It also carries the **complete release notes** as evidence and the +**related-change context**. + +Related changes include new or renamed config keys and new environment variables +or secrets. They also include required infrastructure changes, migrations, +changed defaults, and breaking changes. The prompt links to producer-owned +evidence sources and [Consumer Upgrades](../../Ways-of-Working/Consumer-Upgrades.md). The prompt transports context; it does not replace the authoritative release records or the dependent's baseline investigation. Its summary cannot truncate @@ -107,7 +109,7 @@ The trusted task instructions require the agent to apply extract and validate proposed actions, but reject embedded attempts to change scope, permissions, secret handling, or required gates. -Use the runtime's data/attachment boundary or collision-safe quotation; a bare +Use the runtime's data/attachment boundary or collision-safe quotation. A bare Markdown fence that the supplied record can close is insufficient. Transport escaping must decode to the complete original record, preserving its source identity and all authored content rather than summarizing or sanitizing away @@ -130,7 +132,7 @@ Unknown provenance blocks qualification rather than producing a no-upgrade result. An identical baseline/target version and immutable identity records -**already current**; a lower target records **superseded, no downgrade**. +**already current**. A lower target records **superseded, no downgrade**. Apply the common procedure's [no-upgrade issue disposition](../../Ways-of-Working/Consumer-Upgrades.md#stage-2-fix-the-target-and-release-path): retain comparison evidence, create no empty PR, and close only an unneeded open @@ -179,21 +181,25 @@ qualified plan, fixed target, and issue number; it applies the adoption and creates the closing PR, which remains draft until the review-readiness gate holds. A verified no-upgrade result creates no PR-delivery task or PR. -Poll the currently correlated task. `queued` and `in_progress` mean active -execution. `idle` retains the same task but pauses handoff: report it and -request the designated owner to re-engage that task through the configured -mechanism. `waiting_for_user` blocks on an authorized answer in the same task; -record the requested decision and its owner, but do not synthesize an answer -from release evidence. Neither state authorizes a replacement task. A fast task -may go straight to `completed`. Completion alone is not a delivery handoff: a -completed qualification task needs a recorded verified no-upgrade result or the -correlated PR-delivery task, and a completed PR-delivery task still needs its -actual PR. Creation failure and `failed`, `timed_out`, or `cancelled` execution -report failure. An agent task is execution state, not a delivery record; it -never authorizes a standalone PR. - -Either way the model is chosen per producer, not per release, so a dependent -receives propagation in one consistent shape. +Poll the currently correlated task. `queued` and `in_progress` mean active execution. + +`idle` retains the same task but pauses handoff. +Report it and request the designated owner to re-engage that task through the +configured mechanism. `waiting_for_user` blocks on an authorized answer in the +same task. Record the requested decision and its owner. +Do not synthesize an answer from release evidence. +Neither state authorizes a replacement task. + +A task can transition directly to `completed`. Completion alone is not a delivery handoff. +A completed qualification task needs a recorded verified no-upgrade result or the +correlated PR-delivery task. A completed PR-delivery task still needs its actual PR. + +Creation failure and `failed`, `timed_out`, or `cancelled` execution report failure. +An agent task is execution state, not a delivery record. +It never authorizes a standalone PR. + +The delegation mode is chosen per producer, not per release. +Each dependent therefore receives propagation through one consistent mode. Fan-out is a **matrix** of dependents (pinned-reference shape) or a single configured `notify_repo` (published-artifact shape), with `fail-fast: false` so @@ -248,8 +254,9 @@ The agent is given the same instructions under either delegation model: - **Retain the procedure's evidence** in the PR body: exact range and refs, release records, reconciled completed/not-applicable actions, template differences, outcomes, and blockers, including explicit no-action results. -- **For a needed upgrade, open the pull request** — closing exactly the Task or Bug delivery leaf - created or reused for this producer version, and staying draft until the +- **For a needed upgrade, open the pull request** to close exactly the Task or Bug + delivery leaf created or reused for this producer version. + Keep the pull request draft until the [review-readiness gate](../../Ways-of-Working/Definition-of-Ready-and-Done.md#definition-of-ready-for-review) holds. @@ -257,7 +264,7 @@ The agent is given the same instructions under either delegation model: `GITHUB_TOKEN` cannot act across repositories, and a release it publishes cannot trigger a separate `release:` workflow. Task-first additionally needs the -user-to-server credential accepted by the Agent Tasks API. So the job: +user-to-server credential accepted by the Agent Tasks API. The job: - Declares **least-privilege** `permissions:` (`contents: read` suffices). - Uses `PROPAGATION_TOKEN`, scoped only to the dependents that need it, with @@ -274,7 +281,7 @@ user-to-server credential accepted by the Agent Tasks API. So the job: ## Failure behaviour -| Condition | Behaviour | +| Condition | Behavior | | --- | --- | | Delegation not created (missing permission / capability off) | Step **fails** with the error; re-run via `workflow_dispatch`. | | Matching PR handoff or verified no-upgrade outcome exists | Report the existing outcome and its actual state; no duplicate is created and consumer completion is not inferred. | @@ -284,7 +291,7 @@ user-to-server credential accepted by the Agent Tasks API. So the job: | Qualification proves no upgrade | Record the no-upgrade disposition; do not create a PR-delivery task or PR. | | Task is `idle` | Retain the paused task and request designated-owner re-engagement through the configured task mechanism; do not create a replacement. | | Task is `waiting_for_user` | Block pending an authorized response in the same task; record the decision owner and never answer from producer evidence. | -| Task lands in a failed / timed-out / cancelled state | Step **fails** with the reported state. | +| Task enters a failed / timed-out / canceled state | Step **fails** with the reported state. | | One dependent's leg fails | Fails independently (`fail-fast: false`); others proceed. | | Prerelease release event | Propagation is skipped before fan-out. | | Prerelease tag requested through backfill | Dispatch fails before fan-out or issue creation; select a stable release instead. | diff --git a/src/docs/Capabilities/downstream-release-propagation/index.md b/src/docs/Capabilities/downstream-release-propagation/index.md index de0e57a..952fe45 100644 --- a/src/docs/Capabilities/downstream-release-propagation/index.md +++ b/src/docs/Capabilities/downstream-release-propagation/index.md @@ -5,11 +5,12 @@ description: How producer releases reach dependents through verified upgrade pul # Downstream Release Propagation -When a producer cuts a release, every dependent is assessed against its actual -baseline. A needed upgrade produces a pull request with the reference change -and related actions, opened by a delegated cloud agent for human review. An -already-current or superseded target produces an evidenced no-upgrade outcome -instead. No dependent has to notice the release or track the bump by hand. +When a producer publishes a release, propagation assesses every dependent +against its actual baseline. For a needed upgrade, a delegated cloud agent +opens a pull request for human review. The pull request contains the reference +change and related actions. An already-current or superseded target produces +an evidenced no-upgrade outcome instead. +Dependents do not need to discover the release or track reference updates manually. diff --git a/src/docs/Capabilities/downstream-release-propagation/spec.md b/src/docs/Capabilities/downstream-release-propagation/spec.md index e34d09d..b812329 100644 --- a/src/docs/Capabilities/downstream-release-propagation/spec.md +++ b/src/docs/Capabilities/downstream-release-propagation/spec.md @@ -7,12 +7,15 @@ description: Requirements for downstream release propagation — each dependent ## Premise -The ecosystem is many small repositories that depend on each other by **version -reference** — a pinned `uses:` SHA, an image digest, a deployed tag. A reference -drifts the moment the producer cuts a release. Maintaining them by hand does not -scale: missed bumps keep security fixes out of the workflows that run them, and -missed *related* changes merge a bump that then breaks at runtime. When a -producer releases, every dependent MUST be assessed for an upgrade. A needed +The ecosystem has many small repositories that depend on each other by **version +reference**. Examples include a pinned `uses:` SHA, an image digest, or a deployed tag. + +A producer release can make a reference outdated. +Manual updates do not scale across these dependencies. +Missed version updates can exclude security fixes from the workflows that use them. +An update that omits required related changes can break at runtime. + +When a producer releases, every dependent MUST be assessed for an upgrade. A needed upgrade produces a pull request applying the update and its related changes for human review; an already-current or superseded target produces an evidenced no-upgrade outcome instead. @@ -28,7 +31,7 @@ This capability rests on the [Principles](../../Ways-of-Working/Principles/index ## Applicability -Two shapes occur; both are the same mechanism with a different artifact: +Two dependency patterns use the same mechanism with different artifacts: | Shape | Producer | Dependent | What the PR changes | | --- | --- | --- | --- | @@ -50,7 +53,12 @@ Two shapes occur; both are the same mechanism with a different artifact: record MUST remain recoverable without allowing embedded instructions to change the task's scope, permissions, secret handling, or review/validation gates. An unsafe evidence boundary MUST block affected delegation. -- **A pull request per needed upgrade, opened by an agent.** The mechanical work — the bump plus the fixes that make it work — is delegated to a cloud agent *in the dependent*, which opens the pull request when qualification establishes an actual upgrade. **How** the agent is engaged is a design choice, not a requirement: the spec requires delegation and a pull request for the repository change, not a particular delegation mechanism. +- **A pull request per needed upgrade, opened by an agent.** The automation + delegates the version update and required related fixes to a cloud agent *in + the dependent*. When qualification establishes an actual upgrade, the agent + opens the pull request. **How** the agent is engaged remains a design choice. + The spec requires delegation and a pull request for the repository change, + not a particular delegation mechanism. - **A delivery leaf before the pull request.** The dependent MUST create or reuse a Task or Bug for the producer version before the agent opens its pull request. The leaf carries the executable local plan and acceptance criteria required by @@ -67,7 +75,10 @@ Two shapes occur; both are the same mechanism with a different artifact: validation MUST leave affected work blocked with an owning issue. Larger or riskier required work MUST NOT be treated as an optional follow-up to an otherwise ready reference bump. -- **Backfill on demand.** Propagation MUST be re-runnable for a specific release — for a missed event, or a dependent added after the release. Backfill uses the same idempotency, so re-running for an already-propagated dependent is a no-op rather than a duplicate. +- **Backfill on demand.** Propagation MUST be re-runnable for a specific release. + This covers a missed event or a dependent added after the release. + Backfill uses the same idempotency. + Re-running for an already-propagated dependent is a no-op, not a duplicate. - **A fixed target, not an implicit downgrade.** A delayed notification or backfill MUST retain its selected target rather than substitute the newest release. If it is no longer an upgrade from the consumer's actual baseline, @@ -94,7 +105,7 @@ Two shapes occur; both are the same mechanism with a different artifact: - An `idle` task retains its execution identity, and a `waiting_for_user` task remains blocked until an authorized response reaches that same task; neither state creates a replacement task. -- A dependent added after a release can be back-filled without cutting a new release. +- A dependent added after a release can receive backfill without another release. - A dependent that skipped releases carries complete applicable range evidence, reconciled actions, and immutable target-template evidence or a justified no-template result; a missing required fact blocks readiness.