From ff0a3f2d0b565f7cc57a82fe6f03533c5e0fda4e Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Thu, 9 Jul 2026 17:50:22 -0600 Subject: [PATCH] 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 --- .../release-openclaw-maintainer/SKILL.md | 65 ++++- .../references/extended-stable-backports.md | 270 ++++++++++++++++++ 2 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 .agents/skills/release-openclaw-maintainer/references/extended-stable-backports.md diff --git a/.agents/skills/release-openclaw-maintainer/SKILL.md b/.agents/skills/release-openclaw-maintainer/SKILL.md index 34b7c9a9be5b..584f88dc3c7f 100644 --- a/.agents/skills/release-openclaw-maintainer/SKILL.md +++ b/.agents/skills/release-openclaw-maintainer/SKILL.md @@ -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 `. - 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` diff --git a/.agents/skills/release-openclaw-maintainer/references/extended-stable-backports.md b/.agents/skills/release-openclaw-maintainer/references/extended-stable-backports.md new file mode 100644 index 000000000000..9af0698665d4 --- /dev/null +++ b/.agents/skills/release-openclaw-maintainer/references/extended-stable-backports.md @@ -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 "" "$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 "" "$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 "" "$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.