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/CONTRIBUTING.md b/CONTRIBUTING.md index 57ace05..58fb822 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -40,8 +40,10 @@ 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 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. 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: 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: