distribution-vet
CommandMaintainer-only. Classifies every file that would newly ship to adopters against the written distribution-boundary categories,…
Maintainer-only. Cuts a new GAIA release. Bumps the version, graduates the CHANGELOG, regenerates the manifest, opens the release PR, then tags on merge.
$ npx -y skills add gaia-harness/gaia --agent claude-code
name: gaia-release description: Maintainer-only. Cuts a new GAIA release. Bumps the version, graduates the CHANGELOG, regenerates the manifest, opens the release PR, then tags on merge. disable-model-invocation: true argument-hint: "patch|minor|major"
Contents: Required argument; Pre-flight: Worktree check; Workflow; Recovery: I tagged on the wrong commit.
Cut a new GAIA release. Thin orchestrator over the `.gaia/cli/gaia-maintainer release` CLI namespace, which owns every deterministic step (preflight checks, semver bump, CHANGELOG graduation, wiki scrub, manifest regen, commit + tag dance). This command sequences the CLI subcommands and surfaces user-facing prompts where human judgment is required.
This command is **maintainer-only**: it and the `gaia-maintainer` binary are release-excluded.
> [!important] `main` is protected > Direct pushes to `main` are blocked. The release commit lands on a release branch, goes through a PR, and the tag is created on the squash commit _after_ it lands on `main`. The release PR is subject to the same CI gate and the same Code Audit Team merge handshake as any other PR, with one narrowing. When its whole change is release bookkeeping (Steps 2 and 5 to 8, nothing else) and it was cut from main's green head, it takes the release fast path: each required job runs `release manifest --check` in place of its suite and reports green in about a minute, and the audit resolver names no member (Step 10). `.gaia/scripts/release-bookkeeping-check.sh` is the one predicate both read; its header owns what counts as bookkeeping. Any other change, including bundles Step 7b rebuilt, a base main has since moved past, or a main that is not green, runs every gate in full: expect `Vitest and Playwright`, `Run Chromatic`, and `Vitest (.gaia/cli)`, the last on its full typecheck, lint, vitest, and bundle-freshness path, since a release PR bumps root `package.json`, which that job's paths filter lists. `gh pr merge --squash --auto` is the normal path: the repository allows squash merges only, and base-branch protection rejects a merge without `--auto`, so `--auto` is required to queue the merge until checks pass. See `wiki/concepts/PR Merge Workflow.md`.
Invocation: `/gaia-release patch|minor|major`. The argument is the **sole authority** for the version bump.
If the argument is missing, including when `/gaia-release` is reached as part of a larger batch of work ("ship this then release", a multi-step plan that ends in release, a chained workflow), **STOP and ask the maintainer via `AskUserQuestion`** before any preflight / branch / commit step. Do not infer the bump from commit prefixes, diff size, or the `gaia-maintainer release bump` proposal.
The conventional-commit scan over-proposes `minor` for CI/plumbing commits incorrectly tagged `feat:` that are patch-level in spirit; the maintainer is the only reliable source for semver intent. Never proceed without an explicit `patch|minor|major` from the maintainer.
This command bumps `.gaia/VERSION`, commits and tags on `main`, and opens the release PR, all main-checkout operations that must never run from a per-SPEC worktree branch. If invoked from a linked worktree, reject hard: `gaia_refuse_if_worktree` (`.gaia/scripts/main-only-lib.sh`) asks the shared resolver which tree this is and refuses out loud, naming the main checkout, when the answer is a worktree.
Detection (run this first, before anything else):
. .gaia/scripts/main-only-lib.sh gaia_refuse_if_worktree "/gaia-release" || exit 1
The CLI surface is the source of truth. The classification rules for `.gaia/manifest.json` live in code (`.gaia/cli/src/release/manifest.ts`); the on-disk manifest is the single source of truth for `/update-gaia` consumers.
.gaia/cli/gaia-maintainer release preflight bash .gaia/scripts/verify-required-checks.sh bash .gaia/scripts/verify-main-green.sh
`verify-required-checks.sh` confirms every context in its own `REQUIRED_CONTEXTS` list is required by the default branch's live rules. Exit 1 names the contexts missing from those rules; exit 2 means it could not resolve the repository or read its rules. On non-zero, STOP and report.
`verify-main-green.sh` refuses while main is red: an open `ci-red-main` issue, or a push-to-main run of `GAIA: Audit CI Tests` on the commit that is not `success`. A pull request runs only the bats suites its change can affect, and the full suite on main is the backstop for the rest, so a release cut from a red main can ship a defect no pull request run saw. Its header owns the exit codes. On non-zero, STOP and relay its refusal, which names the run or issue and the repair: fix main, wait for a run still in progress (`gh run watch <id>`), or rerun a flaky leg (`gh run rerun <id> --failed`). There is no bypass. Steps 11 and 12 run it again.
Verifies: on `main`, clean working tree, and `wiki/.state.json` is current. The wiki check reads `gaia wiki state --json`: a reachable state passes on `commits_ahead === 0`; an orphaned state (`reachable:false`, the normal post-squash-merge condition, where `commits_ahead` is `0`) is judged on `drift_count`, counted from the orphaned SHA while its object is present locally and from `suggested_base` otherwise, so an un-evaluated window isn't read as a silent zero. Either way, drift that is only wiki-sync squash artifacts passes; substantive drift exits non-zero with an explanation. STOP and report; the maintainer fixes (commit, push, run bare `/gaia-wiki`, which runs sync, consolidate prompts, and lint's fix loop (which can file tech-debt issues) and lands them through its own PR, so expect it to finish before re-running `/gaia-release`).
Use the maintainer's argument from "Required argument" as `<BUMP>`. The CLI's `release bump` proposal is **informational only**, print it for awareness, then proceed with `<BUMP>` regardless:
``
Claude is raw power. GAIA is order and focus. A serious harness for Claude Code. It keeps Claude-shipped code production-grade as your team scales. The React frontend is handled. You build the rest of your app on top.
Maintainer-only. Classifies every file that would newly ship to adopters against the written distribution-boundary categories,…
Cleanses memory and auto-loaded files (CLAUDE.md, rules) of duplication with the wiki, contradictions with the wiki, and stale…
Drafts a guard (deterministic check, skill, or path-scoped rule) for a recurring code-audit finding class, with approval. Reviews…
Fixes the tech-debt backlog, a single issue, a recommended related batch, or an optional batch of small unrelated issues, highest…
Lints this project's Claude integration (skills, commands, agents, rules, hooks, settings, CLAUDE.md files, wiki) with a…
Turns a GAIA workflow misfire into a redacted, classified, filing-ready bug report in one read-only pass. Self-diagnoses config…
Implement tasks incrementally — build, test, verify, commit. Add "auto" to run the whole plan in one approved pass.