docs(skills): add backporting to release maintainer (#99266)

* docs(skills): add stable backport workflow

* docs(skills): prepare complete stable patch sets

* docs(skills): align backports with extended stable

* docs(skills): fold backports into release maintainer

* docs(release): clarify plugin selector repair
This commit is contained in:
Dallin Romney
2026-07-09 17:50:22 -06:00
committed by GitHub
parent 991262e2e7
commit ff0a3f2d0b
2 changed files with 332 additions and 3 deletions

View File

@@ -1,11 +1,15 @@
---
name: release-openclaw-maintainer
description: Prepare or verify OpenClaw stable/beta releases, changelogs, release notes, publish commands, and artifacts.
description: Prepare or verify OpenClaw stable, beta, and extended-stable releases, including backport discovery, changelogs, release notes, publish commands, and artifacts.
---
# OpenClaw Release Maintainer
Use this skill for release and publish-time workflow. Load `$release-private` if it exists before resolving Peter-owned credential locators or private host topology. Keep ordinary development changes and GHSA-specific advisory work outside this skill.
Use this skill for release and publish-time workflow, including preparing the
approved backport set for an extended-stable maintenance release. Load
`$release-private` if it exists before resolving Peter-owned credential
locators or private host topology. Keep ordinary development changes and
GHSA-specific advisory work outside this skill.
## Respect release guardrails
@@ -138,9 +142,64 @@ prepare-run <PR>`.
- When asked to announce on X, use `~/Projects/bird/bird` and follow the
release tweet style below.
## Prepare extended-stable backports
When asked to create the initial `.33` extended-stable line or a later
maintenance patch, read
`references/extended-stable-backports.md` and follow it before version, tag, or
publication work. Treat backport discovery and preparation as an ability of
this release skill, not as a separate release workflow.
The backport ability owns the complete mainline inventory, private-security
reconciliation, candidate decisions, maintainer approval, coordinated staging
PR, and proof handoff. After that PR lands, use the dedicated npm-only sequence
below. Never route `.33+` through the regular beta/stable release sequence.
## Publish extended-stable releases
Use this path only for the trailing completed month's `.33+` line. Treat
`docs/reference/RELEASING.md`,
`scripts/openclaw-npm-extended-stable-release.mjs`, and the release workflows
on pinned current `main` as the exact command and validation contract.
1. Check out the canonical `extended-stable/YYYY.M.33` branch after the
approved backport PR lands. Require its tip, root package version, every
publishable official plugin version, and intended immutable `vYYYY.M.P` tag
to identify one exact release commit.
2. Create and push `vYYYY.M.P` at that exact branch tip only after version prep
and focused backport proof are complete.
3. Dispatch `openclaw-npm-release.yml` with `preflight_only=true` and
`npm_dist_tag=extended-stable` from the canonical branch. Save the successful
npm preflight run ID.
4. Dispatch `full-release-validation.yml` from the same branch with
`ref=extended-stable/YYYY.M.33` and `release_profile=stable`. Save the
successful exact-head validation run ID.
5. Dispatch `plugin-npm-release.yml` from the same branch with
`publish_scope=all-publishable`, the full release SHA as `ref`, and
`npm_dist_tag=extended-stable`. Require complete exact-version and selector
readback, then save the successful plugin run ID.
6. Dispatch the real `openclaw-npm-release.yml` publish from the same branch
with the intended tag, `npm_dist_tag=extended-stable`, and all three saved
run IDs. The workflow must publish the exact prepared core tarball and prove
the referenced runs match the canonical branch and release SHA.
7. Independently verify the exact core package, every official plugin package,
and all `extended-stable` selectors. If only the core selector readback
fails, use the `openclaw` repair command generated by the core workflow. If
an official-plugin selector is missing or stale for an already-published
version, use the approved credential-isolated release tooling for manual
plugin tag repair; the OIDC source workflow cannot mutate that tag. Never
republish an immutable version.
8. Do not create a GitHub Release or publish macOS, Windows, Docker, mobile,
website, ClawHub, or private dist-tag artifacts from this path.
## Keep release channel naming aligned
- `stable`: tagged releases only, published to npm `beta` by default; operators may target npm `latest` explicitly or promote later
- `stable`: user updates resolve npm `latest`; tagged regular releases publish
to npm `beta` by default, then operators may target or promote to `latest`
explicitly
- `extended-stable`: user updates resolve npm `extended-stable`; operators
publish the trailing completed month's `.33+` line from
`extended-stable/YYYY.M.33`
- `beta`: prerelease tags like `vYYYY.M.PATCH-beta.N`, with npm dist-tag `beta`
- Prefer `-beta.N`; do not mint new `-1` or `-2` beta suffixes
- `dev`: moving head on `main`

View File

@@ -0,0 +1,270 @@
# Extended-Stable Backport Preparation
Prepare the next npm maintenance patch for the active `extended-stable` line.
Discover the complete candidate set, obtain maintainer approval, and prepare
the approved commits as one coordinated PR. Treat commits as canonical; use
PRs, issues, ClawSweeper reports, and advisories as supporting context.
## Boundaries
- Read `docs/reference/RELEASING.md`,
`scripts/openclaw-npm-extended-stable-release.mjs`, and the relevant release
workflows from a pinned current `origin/main` before resolving the line.
- Target npm `extended-stable` and the canonical
`extended-stable/YYYY.M.33` branch. The user-facing `extended-stable` update
channel resolves that selector; user-facing `stable` continues to resolve
npm `latest`.
- Cover the core `openclaw` package and every npm-publishable official plugin
included by the canonical `all-publishable` release inventory at the same
exact version.
- Exclude ClawHub publication, GitHub Releases, native apps, Docker images,
mobile artifacts, website downloads, and private-repository dist-tags.
- Review the complete mainline delta. Do not stop after the first obvious
fixes or consider public PRs the complete source set.
- Present the full proposed release set before changing release refs.
- Never push directly to the canonical branch, create a release tag, publish a
package, or mutate an npm dist-tag during discovery or staging.
- Never use `bypass_extended_stable_guard=true` for production.
- Reject features, broad refactors, speculative hardening, and changes that
require new config, migrations, APIs, protocols, dependencies, runtime
requirements, or operator action.
- Read `SECURITY.md` and use `$security-triage` for security candidates. Route
unpublished advisory work through `$openclaw-ghsa-maintainer`; never expose
private details before the security owner authorizes disclosure.
- Use `$openclaw-testing` for proof selection, `$autoreview` before handoff,
and `$openclaw-pr-maintainer` for GitHub operations.
## Resolve the Active Line
1. Run `git status -sb`. Do not overwrite unrelated work.
2. Fetch current `origin/main`, tags, and `extended-stable/*` branches.
3. Pin the fetched `origin/main` SHA. Read the release contract from that exact
commit before resolving versions, package scope, or branches.
4. Query npm dist-tags and choose exactly one mode:
- **Existing line:** `extended-stable` exists. Treat its exact final
`YYYY.M.PATCH` value as the published baseline; require `PATCH >= 33` and
no prerelease or correction suffix.
- **Bootstrap:** the selector is absent. Obtain explicit maintainer approval
for the completed `YYYY.M` month and exact final base tag. Do not infer the
base solely from `latest`, which may already have advanced.
5. Derive the only valid branch as `extended-stable/YYYY.M.33`.
- Existing line: require the branch to exist, its `package.json` version to
equal the selector, and `vYYYY.M.PATCH` to resolve to the branch tip.
- Bootstrap: use the approved base tag for discovery. If the canonical
branch exists, require its tip to equal the approved base commit and reject
unexplained unpublished changes. Do not create the remote branch during
discovery.
6. Confirm the published baseline or approved bootstrap base resolves from npm
and its Git tag resolves to the expected commit.
7. Confirm `origin/main` has an exact final version in a strictly later
calendar month with a patch below `33`, matching the production guard.
8. Choose the intended version:
- bootstrap: exact final `YYYY.M.33`;
- existing line: the next unused final patch on the same `YYYY.M` line,
normally `PATCH + 1` and always `>= 34`.
9. Verify the intended core and official-plugin versions are absent from npm.
Use an isolated npm config for unauthenticated registry reads:
```bash
npm_userconfig=$(mktemp)
trap 'rm -f "$npm_userconfig"' EXIT
dist_tags=$(npm view openclaw dist-tags --json --userconfig "$npm_userconfig")
published_version=$(printf '%s' "$dist_tags" | jq -r '."extended-stable" // empty')
if [[ -n "$published_version" ]]; then
npm view "openclaw@${published_version}" version \
--userconfig "$npm_userconfig"
fi
```
Do not use GitHub's latest nonprerelease Release as the source of truth. The
extended-stable lane intentionally creates no GitHub Release. In bootstrap
mode, record the approving maintainer and approved base commit. Stop before
discovery or mutation if npm, the canonical branch, tags, package versions,
approved base, or protected `main` disagree.
## Build the Complete Commit Inventory
Freeze `scan_end` to the pinned `origin/main` SHA. Resolve `scan_start` in this
order:
1. the prior accepted extended-stable backport evidence's recorded `scan_end`;
2. for the first run, the merge base between the canonical branch and `main`;
3. an explicitly audited maintainer-provided mainline cursor when histories are
unrelated.
Never reuse a cursor from an open, abandoned, partially landed, or rejected PR.
Load unresolved `blocked` candidates from the accepted prior evidence before
classifying new commits. Advance the cursor only when those candidates remain
durably recorded for the next run.
```bash
scan_end=$(git rev-parse origin/main)
scan_start=${PRIOR_ACCEPTED_SCAN_END:-}
if [[ -z "$scan_start" ]]; then
scan_start=$(git merge-base "<canonical-extended-stable-ref>" "$scan_end")
fi
git merge-base --is-ancestor "$scan_start" "$scan_end"
git log --reverse --format='%H%x09%ad%x09%an%x09%s' --date=short \
"$scan_start..$scan_end"
git cherry "<canonical-extended-stable-ref>" "$scan_end" "$scan_start"
```
If no auditable start exists, stop rather than guessing from dates or titles.
Create an uncommitted scratch ledger with one row per non-equivalent commit.
Process deterministic batches of at most 100 commits. Record each SHA, subject,
changed paths, first-pass decision, and missing evidence.
```bash
ledger_dir=$(mktemp -d)
git rev-list --reverse "$scan_start..$scan_end" >"$ledger_dir/all-commits.txt"
git cherry "<canonical-extended-stable-ref>" "$scan_end" "$scan_start" \
>"$ledger_dir/patch-equivalence.txt"
split -l 100 "$ledger_dir/all-commits.txt" "$ledger_dir/batch-"
```
Review every ledger entry's subject and changed-file summary. Inspect the full
diff and surrounding code for every plausible security or reliability fix.
Account for merges, squash commits, direct commits, reordered patches,
branch-specific equivalents, and companion commits that `git cherry` misses.
Do not finish while any entry remains unclassified.
Also inspect direct maintainer/security commits, linked PRs and issues,
ClawSweeper findings, companion fixes, callers, siblings, tests, and dependency
contracts.
## Filter by Publication Surface
Include only fixes that affect the core package or an npm-publishable official
plugin in the exact release inventory. Prove package inclusion rather than
inferring it from the source path alone.
- Do not exclude `extensions/**` by path. Determine whether the package appears
in the canonical `all-publishable` inventory.
- Include plugin fixes only when the canonical workflow publishes that package
at the same intended version and can verify its exact package and selector.
- Treat ClawHub-only, external, private, or otherwise unlisted plugin changes as
out of scope.
- Treat native-only, Docker-only, mobile-only, website-only, and GitHub
Release-only fixes as `skip` for this npm-only line.
- Treat cross-repository or package-topology uncertainty as `blocked` until the
shipped npm surface and release owner are proven.
Prioritize crashes, hangs, restart loops, data/session/message loss,
auth/provider failures, serious mature-behavior regressions,
release/update/rollback failures, and bounded resource exhaustion. Do not
exclude a commit because its title lacks `fix:` or it has no PR.
## Reconcile Private Security Work
Before calling the release set complete, use `$security-triage` and
`$openclaw-ghsa-maintainer` to:
1. enumerate authorized open/draft advisories and private-fork fix state;
2. determine privately whether each item affects a published npm package in the
extended-stable release inventory;
3. route applicable unpublished fixes through the approved private workflow;
4. expose only an opaque pending/cleared status publicly.
If advisory access is unavailable, require explicit security-owner
confirmation. Never copy advisory titles, exploit details, private SHAs, or
private refs into the public ledger, branch, PR, or chat output.
## Assess Every Plausible Fix
For each candidate, prove:
1. The faulty behavior exists in the published extended-stable package set or
canonical branch.
2. The public source commit is on `main` and is not already present or
behaviorally equivalent on the branch.
3. The change restores existing behavior instead of adding functionality.
4. The fix includes all required companion commits.
5. Any branch-specific adaptation is narrow and preserves the invariant.
6. Focused validation can prove the fix on the maintenance branch.
7. The complete fix ships through the canonical npm publication inventory.
Classify each plausible fix as:
- `backport`: applicable, material, isolated, npm-shipped, and testable;
- `already-covered`: commit or equivalent behavior is present;
- `not-affected`: the published package set does not contain the defect;
- `blocked`: useful, but adaptation, package scope, or proof is incomplete;
- `skip`: feature, low-impact change, refactor, or out-of-scope surface.
Do not infer that a clean cherry-pick is safe. Treat config/default, persisted
state, plugin/API boundary, protocol, dependency, packaging, installer, and
cross-repository changes as high risk requiring maintainer judgment.
## Present the Full Release Set
Before mutation, report:
| Source commit | Decision | Published impact | Dependencies | Adaptation | Proof |
| ------------- | -------- | ---------------- | ------------ | ---------- | ----- |
Include the published npm selector/version, canonical branch, intended patch,
protected `main` version, scan bounds, total commits, batch count, dependency
order, complete proposed set, blocked/high-risk decisions, carry-forward items,
affected core/plugin packages, out-of-scope publication surfaces, and
confidential security status.
Use PR links when they exist, but retain source commit identities in internal
evidence. Obtain explicit maintainer approval for the complete release set
before changing branches.
## Prepare the Approved Patch Set
1. Resolve the exact target commit. In existing-line mode, use the canonical
remote head. In bootstrap mode, use the approved base commit; after release
set approval, create the canonical branch from that exact commit if it is
still absent. Re-fetch and verify it before creating a separate staging
branch.
2. Apply each approved public source commit in dependency order with
`git cherry-pick -x`. Keep commits separate and avoid unrelated cleanup.
3. Compare every result with the source diff and maintenance branch. Return a
candidate to `blocked` if adaptation becomes architectural.
4. Backport or add focused regression tests where practical. Run focused proof
per fix, then combined changed-surface and release-relevant checks. Use
Crabbox/Testbox for broad, package, cross-OS, release, or E2E proof.
5. Set the intended root version and run `pnpm release:prep` on the same staging
branch. Verify every publishable official extension package has that exact
version. Do not create the tag or dispatch publication before the PR lands.
6. Run `$autoreview` until no accepted/actionable findings remain.
7. Open one coordinated PR targeting the canonical extended-stable branch.
Never target `main` and never push the target branch directly.
8. Keep unpublished security work in the approved private advisory fork until
disclosure is authorized.
The PR body must list the intended maintenance tag, exact npm publication
inventory, every source commit and optional PR, impact, adaptations, focused
and combined proof, security status, rollback considerations, and exact scan
bounds. Record unresolved blocked candidates so the next run carries them
forward.
## Handoff
Report:
- mode, published `openclaw@extended-stable` version or approved bootstrap
base, and canonical branch;
- intended maintenance tag and final staging head;
- included, skipped, blocked, not-affected, and already-covered candidates;
- affected core/plugin packages, adaptations, and commit order;
- proof commands, run IDs, and autoreview result;
- remaining security, release, or maintainer approvals;
- the coordinated PR URL or why no PR was opened;
- explicit confirmation that no non-npm publication is planned.
After the PR lands, continue with this skill's canonical extended-stable
release flow. Require exact branch-tip/tag/package identity; run npm preflight
and Full Release Validation from the canonical branch; publish every
npm-publishable official plugin from the exact release SHA; publish the
prepared core tarball with the referenced successful run IDs; verify every
exact package and `extended-stable` selector; and preserve the generated
core `openclaw` selector-repair command. Repair missing or stale official-
plugin selectors on already-published versions with the approved credential-
isolated release tooling for manual tag repair; the OIDC source workflow cannot
mutate those tags. Never republish an immutable version when only a selector
needs repair.