From 1e30b1cc583262dfc8fa5a7f483174edaade3d45 Mon Sep 17 00:00:00 2001 From: claude Date: Mon, 24 Aug 2026 18:59:45 +0000 Subject: [PATCH] docs(adr): record ADR-0125 as accepted, and name the version-PR trigger in PD #15 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two sentences, two governed files, nothing else. 1. `docs/adr/0125-...md` line 3 declared itself "Proposed (2026-08-20) — awaiting the maintainer's hand-merge" while being the authority the publish lane cites eleven times. The merge it says it awaits is, by its own text, the acceptance act; that merge landed as 81d1fa11d (#10150) on 2026-08-20. The date is read from that merge, not from today. 2. `AGENTS.md` Prime Directive #15 said the Version Packages PR "is regenerated on every push to `main`". The `version-pr` job left the push trigger; it now runs on a six-hourly `schedule` or an on-demand `refresh_version_pr` dispatch. `release.yml`'s `push: branches: [main]` trigger drives the publish lane instead, so the sentence now says which trigger it means. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx --- AGENTS.md | 2 +- .../0125-release-approval-gate-replaces-the-typed-version.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7785a2f80b..2881f48bc0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -191,7 +191,7 @@ Other scripts: `objectui:bump` (pull only), `objectui:build`, `objectui:clean`. > **刚才我也没提出要求,是哪个ai自己替我发了 rc.4,版本发布必须是人工的。这个要写入规范。** - Its last sentence is this directive's warrant: 「这个要写入规范」. A rule that binds every seat has to be readable by every seat — which is why it lives here, not only in a lane-specific skill file. **Release-adjacent work stays open to every seat.** The release board, `.objectui-sha` pin bumps, version reconciliation, writing changesets, compiling release notes when asked, and *verifying* release state (`npm view`, `git ls-remote --tags`) are ordinary tasks. What is reserved is the **release act itself**: ⛔ running `changeset publish` / `pnpm run release`, ⛔ pushing a version tag, ⛔ cutting a GitHub Release, ⛔ pushing a runtime image, ⛔ `workflow_dispatch`-ing `release.yml` or any other publish-capable workflow, ⛔ **approving a pending `release` environment deployment** (ADR-0125 — since 2026-08-20 that click IS the publish authorisation, and a deployment waiting for hours is the system working, not a state you clear), and ⛔ merging — or queueing, or arming auto-merge on — the **Version Packages** PR (`chore: version packages`). That PR is bot-authored and standing-open by design: it is regenerated on every push to `main`, so "green, current, and nobody has objected" is its permanent resting state, not a signal that it is due. When you find a publish nobody ordered — a tag or an npm version that simply appeared — ⛔ do not "repair" it with a counter-publish: file it as an incident for the maintainer. + Its last sentence is this directive's warrant: 「这个要写入规范」. A rule that binds every seat has to be readable by every seat — which is why it lives here, not only in a lane-specific skill file. **Release-adjacent work stays open to every seat.** The release board, `.objectui-sha` pin bumps, version reconciliation, writing changesets, compiling release notes when asked, and *verifying* release state (`npm view`, `git ls-remote --tags`) are ordinary tasks. What is reserved is the **release act itself**: ⛔ running `changeset publish` / `pnpm run release`, ⛔ pushing a version tag, ⛔ cutting a GitHub Release, ⛔ pushing a runtime image, ⛔ `workflow_dispatch`-ing `release.yml` or any other publish-capable workflow, ⛔ **approving a pending `release` environment deployment** (ADR-0125 — since 2026-08-20 that click IS the publish authorisation, and a deployment waiting for hours is the system working, not a state you clear), and ⛔ merging — or queueing, or arming auto-merge on — the **Version Packages** PR (`chore: version packages`). That PR is bot-authored and standing-open by design: `release.yml`'s `version-pr` job regenerates it on a six-hourly `schedule` — or on demand, via the `refresh_version_pr` dispatch input — and never on a push to `main` (that file's `push` trigger drives the publish lane, not this PR), so "green, current, and nobody has objected" is its permanent resting state, not a signal that it is due. When you find a publish nobody ordered — a tag or an npm version that simply appeared — ⛔ do not "repair" it with a counter-publish: file it as an incident for the maintainer. **The precedent is that the mechanical channel fires with nobody deciding to use it.** The release workflow's `on: push` lane once shipped a full release candidate end to end — 69 packages to npm, tags, GitHub Releases, runtime image — with **no human, no dispatch, no seat clicking anything**, twice in one week. So the existence of a path to a release is not authorization to walk it — the same sentence #14 makes about the queue button. ⚠️ **And do not read the YAML as a barrier that holds against you — since ADR-0125 (2026-08-20) it stops very little.** The publish job is triggered by the **push that lands the Version Packages PR** and held at `environment: release` until a required reviewer approves. Read what that costs: the old design's barrier was the `workflow_dispatch` *event*, unforgeable by a push, a queue landing, a bot token or a schedule — never by you, though, since a dispatch is precisely the event an authenticated seat *can* synthesise, which is why this directive stood beside it. That event barrier is gone by choice; what remains is a **repo setting** (required reviewers on `release`) that no file here can assert, that an unprotected environment mimics perfectly in the run log, and that any admin can remove without touching tracked code. So the merge you are already forbidden to perform is now the release trigger: merging `chore: version packages` no longer moves a version number, it **queues a deployment in the maintainer's name** — the single most load-bearing prohibition in this directive. The YAML stops almost nothing now; this directive is the part that stops you. diff --git a/docs/adr/0125-release-approval-gate-replaces-the-typed-version.md b/docs/adr/0125-release-approval-gate-replaces-the-typed-version.md index 4a069bcb39..a47c75e7d4 100644 --- a/docs/adr/0125-release-approval-gate-replaces-the-typed-version.md +++ b/docs/adr/0125-release-approval-gate-replaces-the-typed-version.md @@ -1,6 +1,6 @@ # ADR-0125: The human act that authorises a release is the environment approval, not a typed version string -**Status**: Proposed (2026-08-20) — awaiting the maintainer's hand-merge, which is itself the acceptance act for a governed surface (Prime Directive #14). Implementation ships in the same PR: `.github/workflows/release.yml`. +**Status**: Accepted (2026-08-20) — accepted by the merge that landed it on `main` ([#10150](https://github.com/objectstack-ai/objectstack/pull/10150), commit `81d1fa11d`), which is itself the acceptance act for a governed surface (Prime Directive #14). Implementation shipped in the same PR: `.github/workflows/release.yml`. **Deciders**: ObjectStack Protocol Architects (maintainer ruling, 2026-08-20, on the back of the [#10146](https://github.com/objectstack-ai/objectstack/issues/10146) release failure) **Builds on**: the 2026-08-07 maintainer ruling recorded in **AGENTS.md Prime Directive #15** (「版本发布必须是人工的」) and its implementation in [#6170](https://github.com/objectstack-ai/objectstack/issues/6170) (the two-lane split of `release.yml`) **Supersedes**: nothing. It **re-implements** Prime Directive #15's requirement; the requirement itself is untouched and is quoted again below so no later reader has to reconstruct it.