From c1ecb0c7a34c1bfdf2f1d63521925502b1394160 Mon Sep 17 00:00:00 2001 From: Lan Tian Date: Tue, 22 Sep 2026 15:35:10 +0800 Subject: [PATCH 1/3] docs: QA cuts the release, not a repo maintainer The runbook and CONTRIBUTING both said a maintainer dispatches the Release workflow. QA owns that step: they validate merged `main` against staging and then run the release themselves. Whoever reviews spec-sync PRs should still know the step, since a red release usually comes back to them to diagnose. Co-Authored-By: Claude Opus 5 --- CONTRIBUTING.md | 5 +++-- docs/spec-sync-runbook.md | 13 +++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57ace05..9722cc3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,8 +40,9 @@ All code in the repository can be edited directly, like any other codebase. Please use [Conventional Commits](https://www.conventionalcommits.org/) for commit messages and PR titles (`feat:`, `fix:`, `chore:`, …) — the release changelog is grouped by these prefixes. -Releases are cut manually: a maintainer runs the **Release** workflow (Actions → Release → Run -workflow) and chooses the version bump (patch / minor / major). The workflow lands a +Releases are cut manually, and by QA rather than by a repo maintainer: once they have validated +merged `main` against staging, they run the **Release** workflow (Actions → Release → Run workflow) +and choose the version bump (patch / minor / major). The workflow lands a `release: x.y.z` commit on `main` (version stamping + changelog), tags it, and creates the GitHub Release — which triggers publishing. Ordinary PR merges never trigger a release. diff --git a/docs/spec-sync-runbook.md b/docs/spec-sync-runbook.md index 8f04695..a7f2b34 100644 --- a/docs/spec-sync-runbook.md +++ b/docs/spec-sync-runbook.md @@ -14,7 +14,7 @@ are maintained as a pair and most decisions here apply to both. **staging** spec drifts from the committed snapshot, it opens one PR on a fixed branch (`spec-sync/v1` or `spec-sync/v2`) and announces it in Slack. You review and merge it — the wiring commit is AI-drafted and **always** needs human review. Merging publishes nothing: QA tests merged -`main` against staging first, and a maintainer dispatches the release only after the API has reached +`main` against staging first, and QA cuts the release themselves once the API has reached production. ## 1. Where the signal is: `#ade-sdk-pipeline` @@ -118,11 +118,12 @@ out"): ``` 4. The API reaches **production**. -5. A maintainer dispatches Actions → **Release** → Run workflow and picks the bump - (patch / minor / major). Dispatching **is** the release decision — there is no release PR and no - second confirmation. The workflow stamps the version, prepends the changelog, pushes - `release: x.y.z` to `main`, tags it, and creates the GitHub Release, which triggers - `publish-pypi.yml`. +5. **QA** cuts the release once they have signed off — this step is theirs, not yours: + Actions → **Release** → Run workflow, picking the bump (patch / minor / major). Dispatching + **is** the release decision: there is no release PR and no second confirmation. The workflow + stamps the version, prepends the changelog, pushes `release: x.y.z` to `main`, tags it, and + creates the GitHub Release, which triggers `publish-pypi.yml`. Know this step even though you do + not run it — when a release goes red, diagnosing it usually comes back to you. **A red release is usually not a bug.** The Release workflow's gate 0 is the full V1 + V2 e2e suite against the **live production API**, and nothing downstream runs if it goes red. Two ordinary causes: From c34e771fbcafd0d6642336434f758b7ef7d7e604 Mon Sep 17 00:00:00 2001 From: Lan Tian Date: Tue, 22 Sep 2026 15:39:16 +0800 Subject: [PATCH 2/3] docs: align release.yml header with QA ownership; mark design doc historical MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit release.yml's own header told the reader a maintainer runs it — the one place QA actually reads before dispatching. The Stainless-exit design doc is a dated decision record (Approved 2026-07-07), so its prose is left as written rather than retrofitted; a standing note in its header points at CONTRIBUTING and the runbook as authoritative and names the known divergences, which include the never-wired production-spec release gate. Co-Authored-By: Claude Opus 5 --- .github/workflows/release.yml | 5 +++-- docs/design/stainless-exit-and-v2.md | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 222b8d4..5edc1b2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,8 +1,9 @@ # Manual, dispatch-only release automation (replaces the Stainless-run # release-please after the platform sunset on 2026-09-01). # -# A maintainer runs this workflow (Actions -> Release -> Run workflow) and -# picks the bump: patch / minor / major. The workflow then, in one shot: +# QA runs this workflow (Actions -> Release -> Run workflow) after they have +# validated merged `main` against staging, and picks the bump: patch / minor / +# major. The workflow then, in one shot: # 0. runs the V1 + V2 production e2e suite (.github/workflows/e2e-production.yml) # against the live API — nothing below runs if it goes red, # 1. computes the next version from the latest git tag, diff --git a/docs/design/stainless-exit-and-v2.md b/docs/design/stainless-exit-and-v2.md index 29ce6bc..4e11bb9 100644 --- a/docs/design/stainless-exit-and-v2.md +++ b/docs/design/stainless-exit-and-v2.md @@ -4,6 +4,7 @@ - **Date**: 2026-07-06 - **Scope**: [ade-python](https://github.com/landing-ai/ade-python), [ade-typescript](https://github.com/landing-ai/ade-typescript), one small change in `aide` - **Context**: Stainless (acquired by Anthropic, 2026-05-18) sunsets its platform for our account on **2026-09-01**. +- **Standing**: a dated decision record, not operating documentation. It describes the plan as approved in July 2026; where the pipeline has since moved on, [CONTRIBUTING.md](../../CONTRIBUTING.md#spec-sync-pipeline) and [the spec-sync runbook](../spec-sync-runbook.md) are authoritative and this document is not updated to match. Known divergences: QA cuts releases (this doc says a maintainer does), and the production-spec release gate described below was built as `scripts/spec-sync/release-gate.sh` but never wired into `release.yml`. This design covers three separable problems. They share a deadline and a theme, but each can be discussed, approved, and executed independently: From 87a8aaa78ab7d41b4f654407ba3ce10f93b74076 Mon Sep 17 00:00:00 2001 From: Tian Lan <86591280+tian-lan-landing@users.noreply.github.com> Date: Tue, 22 Sep 2026 17:37:46 +0800 Subject: [PATCH 3/3] Potential fix for pull request finding 'Include production rollout before dispatch' Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- CONTRIBUTING.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9722cc3..58fb822 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,8 +41,9 @@ Please use [Conventional Commits](https://www.conventionalcommits.org/) for comm titles (`feat:`, `fix:`, `chore:`, …) — the release changelog is grouped by these prefixes. Releases are cut manually, and by QA rather than by a repo maintainer: once they have validated -merged `main` against staging, they run the **Release** workflow (Actions → Release → Run workflow) -and choose the version bump (patch / minor / major). The workflow lands a +merged `main` against staging and the API has reached production, they run the **Release** workflow +(Actions → Release → Run workflow) and choose the version bump (patch / minor / major). The workflow +lands a `release: x.y.z` commit on `main` (version stamping + changelog), tags it, and creates the GitHub Release — which triggers publishing. Ordinary PR merges never trigger a release.