Skip to main content

Release Policy

Velaclaw has three public release lanes:
  • stable: tagged releases that publish to npm beta by default, or to npm latest when explicitly requested
  • beta: prerelease tags that publish to npm beta
  • dev: the moving head of main

Version naming

  • Stable release version: YYYY.M.D
    • Git tag: vYYYY.M.D
  • Stable correction release version: YYYY.M.D-N
    • Git tag: vYYYY.M.D-N
  • Beta prerelease version: YYYY.M.D-beta.N
    • Git tag: vYYYY.M.D-beta.N
  • Do not zero-pad month or day
  • latest means the current promoted stable npm release
  • beta means the current beta install target
  • Stable and stable correction releases publish to npm beta by default; release operators can target latest explicitly, or promote a vetted beta build later
  • Every Velaclaw release ships the npm package and macOS app together

Release cadence

  • Releases move beta-first
  • Stable follows only after the latest beta is validated
  • Detailed release procedure, approvals, credentials, and recovery notes are maintainer-only

Release preflight

  • Run pnpm build && pnpm ui:build before pnpm release:check so the expected dist/* release artifacts and Control UI bundle exist for the pack validation step
  • Run pnpm release:check before every tagged release
  • Release checks now run in a separate manual workflow: Velaclaw Release Checks
  • Cross-OS install and upgrade runtime validation is dispatched from the private caller workflow velaclaw/releases-private/.github/workflows/velaclaw-cross-os-release-checks.yml, which invokes the reusable public workflow .github/workflows/velaclaw-cross-os-release-checks-reusable.yml
  • This split is intentional: keep the real npm release path short, deterministic, and artifact-focused, while slower live checks stay in their own lane so they do not stall or block publish
  • Release checks must be dispatched from the main workflow ref so the workflow logic and secrets stay canonical
  • That workflow accepts either an existing release tag or the current full 40-character main commit SHA
  • In commit-SHA mode it only accepts the current origin/main HEAD; use a release tag for older release commits
  • Velaclaw NPM Release validation-only preflight also accepts the current full 40-character main commit SHA without requiring a pushed tag
  • That SHA path is validation-only and cannot be promoted into a real publish
  • In SHA mode the workflow synthesizes v<package.json version> only for the package metadata check; real publish still requires a real release tag
  • Both workflows keep the real publish and promotion path on GitHub-hosted runners, while the non-mutating validation path can use the larger Blacksmith Linux runners
  • That workflow runs VELACLAW_LIVE_TEST=1 VELACLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache using both OPENAI_API_KEY and ANTHROPIC_API_KEY workflow secrets
  • npm release preflight no longer waits on the separate release checks lane
  • Run RELEASE_TAG=vYYYY.M.D node --import tsx scripts/velaclaw-npm-release-check.ts (or the matching beta/correction tag) before approval
  • After npm publish, run node --import tsx scripts/velaclaw-npm-postpublish-verify.ts YYYY.M.D (or the matching beta/correction version) to verify the published registry install path in a fresh temp prefix
  • Maintainer release automation now uses preflight-then-promote:
    • real npm publish must pass a successful npm preflight_run_id
    • stable npm releases default to beta
    • stable npm publish can target latest explicitly via workflow input
    • token-based npm dist-tag mutation now lives in velaclaw/releases-private/.github/workflows/velaclaw-npm-dist-tags.yml for security, because npm dist-tag add still needs NPM_TOKEN while the public repo keeps OIDC-only publish
    • the real publish paths promote prepared artifacts instead of rebuilding them again
  • For stable correction releases like YYYY.M.D-N, the post-publish verifier also checks the same temp-prefix upgrade path from YYYY.M.D to YYYY.M.D-N so release corrections cannot silently leave older global installs on the base stable payload
  • npm release preflight fails closed unless the tarball includes both dist/control-ui/index.html and a non-empty dist/control-ui/assets/ payload so we do not ship an empty browser dashboard again
  • pnpm test:install:smoke also enforces the npm pack unpackedSize budget on the candidate update tarball, so installer e2e catches accidental pack bloat before the release publish path
  • If the release work touched CI planning, extension timing manifests, or extension test matrices, regenerate and review the planner-owned checks-node-extensions workflow matrix outputs from .github/workflows/ci.yml before approval so release notes do not describe a stale CI layout

NPM workflow inputs

Velaclaw NPM Release accepts these operator-controlled inputs:
  • tag: required release tag such as v2026.4.2, v2026.4.2-1, or v2026.4.2-beta.1; when preflight_only=true, it may also be the current full 40-character main commit SHA for validation-only preflight
  • preflight_only: true for validation/build/package only, false for the real publish path
  • preflight_run_id: required on the real publish path so the workflow reuses the prepared tarball from the successful preflight run
  • npm_dist_tag: npm target tag for the publish path; defaults to beta
Velaclaw Release Checks accepts these operator-controlled inputs:
  • ref: existing release tag or the current full 40-character main commit SHA to validate
Rules:
  • Stable and correction tags may publish to either beta or latest
  • Beta prerelease tags may publish only to beta
  • Full commit SHA input is allowed only when preflight_only=true
  • Release checks commit-SHA mode also requires the current origin/main HEAD
  • The real publish path must use the same npm_dist_tag used during preflight; the workflow verifies that metadata before publish continues

Stable npm release sequence

When cutting a stable npm release:
  1. Run Velaclaw NPM Release with preflight_only=true
    • Before a tag exists, you may use the current full main commit SHA for a validation-only dry run of the preflight workflow
  2. Choose npm_dist_tag=beta for the normal beta-first flow, or latest only when you intentionally want a direct stable publish
  3. Run Velaclaw Release Checks separately with the same tag or the full current main commit SHA when you want live prompt cache coverage
    • This is separate on purpose so live coverage stays available without recoupling long-running or flaky checks to the publish workflow
  4. Save the successful preflight_run_id
  5. Run Velaclaw NPM Release again with preflight_only=false, the same tag, the same npm_dist_tag, and the saved preflight_run_id
  6. If the release landed on beta, use the private velaclaw/releases-private/.github/workflows/velaclaw-npm-dist-tags.yml workflow to promote that stable version from beta to latest
  7. If the release intentionally published directly to latest and beta should follow the same stable build immediately, use that same private workflow to point both dist-tags at the stable version, or let its scheduled self-healing sync move beta later
The dist-tag mutation lives in the private repo for security because it still requires NPM_TOKEN, while the public repo keeps OIDC-only publish. That keeps the direct publish path and the beta-first promotion path both documented and operator-visible.

Public references

Maintainers use the private release docs in velaclaw/maintainers/release/README.md for the actual runbook.